keen-botkit
Version:
Bot Kit Integration for Keen IO
2,285 lines • 66.9 kB
JavaScript
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
/*jslint evil: true, regexp: true */
/*members $ref, apply, call, decycle, hasOwnProperty, length, prototype, push,
retrocycle, stringify, test, toString
*/
(function (exports) {
if (typeof exports.decycle !== 'function') {
exports.decycle = function decycle(object) {
'use strict';
var objects = [],
paths = [];
return (function derez(value, path) {
var i,
name,
nu;
switch (typeof value) {
case 'object':
if (!value) {
return null;
}
for (i = 0; i < objects.length; i += 1) {
if (objects[i] === value) {
return {$ref: paths[i]};
}
}
objects.push(value);
paths.push(path);
if (Object.prototype.toString.apply(value) === '[object Array]') {
nu = [];
for (i = 0; i < value.length; i += 1) {
nu[i] = derez(value[i], path + '[' + i + ']');
}
} else {
nu = {};
for (name in value) {
if (Object.prototype.hasOwnProperty.call(value, name)) {
nu[name] = derez(value[name],
path + '[' + JSON.stringify(name) + ']');
}
}
}
return nu;
case 'number':
case 'string':
case 'boolean':
return value;
}
}(object, '$'));
};
}
if (typeof exports.retrocycle !== 'function') {
exports.retrocycle = function retrocycle($) {
'use strict';
var px =
/^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/;
(function rez(value) {
var i, item, name, path;
if (value && typeof value === 'object') {
if (Object.prototype.toString.apply(value) === '[object Array]') {
for (i = 0; i < value.length; i += 1) {
item = value[i];
if (item && typeof item === 'object') {
path = item.$ref;
if (typeof path === 'string' && px.test(path)) {
value[i] = eval(path);
} else {
rez(item);
}
}
}
} else {
for (name in value) {
if (typeof value[name] === 'object') {
item = value[name];
if (item) {
path = item.$ref;
if (typeof path === 'string' && px.test(path)) {
value[name] = eval(path);
} else {
rez(item);
}
}
}
}
}
}
}($));
return $;
};
}
}) (
(typeof exports !== 'undefined') ?
exports :
(window.JSON ?
(window.JSON) :
(window.JSON = {})
)
);
},{}],2:[function(require,module,exports){
var JSON2 = require('./json2');
var cycle = require('./cycle');
JSON2.decycle = cycle.decycle;
JSON2.retrocycle = cycle.retrocycle;
module.exports = JSON2;
},{"./cycle":1,"./json2":3}],3:[function(require,module,exports){
/*
json2.js
2011-10-19
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or ' '),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the value
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
*/
/*jslint evil: true, regexp: true */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
(function (JSON) {
'use strict';
function f(n) {
return n < 10 ? '0' + n : n;
}
/* DDOPSON-2012-04-16 - mutating global prototypes is NOT allowed for a well-behaved module.
* It's also unneeded, since Date already defines toJSON() to the same ISOwhatever format below
* Thus, we skip this logic for the CommonJS case where 'exports' is defined
*/
if (typeof exports === 'undefined') {
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function (key) {
return isFinite(this.valueOf())
? this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z'
: null;
};
}
if (typeof String.prototype.toJSON !== 'function') {
String.prototype.toJSON = function (key) { return this.valueOf(); };
}
if (typeof Number.prototype.toJSON !== 'function') {
Number.prototype.toJSON = function (key) { return this.valueOf(); };
}
if (typeof Boolean.prototype.toJSON !== 'function') {
Boolean.prototype.toJSON = function (key) { return this.valueOf(); };
}
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string'
? c
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
}
function str(key, holder) {
var i,
k,
v,
length,
mind = gap,
partial,
value = holder[key];
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
return String(value);
case 'object':
if (!value) {
return 'null';
}
gap += indent;
partial = [];
if (Object.prototype.toString.apply(value) === '[object Array]') {
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
v = partial.length === 0
? '[]'
: gap
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
: '[' + partial.join(',') + ']';
gap = mind;
return v;
}
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
if (typeof rep[i] === 'string') {
k = rep[i];
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
v = partial.length === 0
? '{}'
: gap
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
: '{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
var i;
gap = '';
indent = '';
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
} else if (typeof space === 'string') {
indent = space;
}
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
return str('', {'': value});
};
}
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
var j;
function walk(holder, key) {
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
j = eval('(' + text + ')');
return typeof reviver === 'function'
? walk({'': j}, '')
: j;
}
throw new SyntaxError('JSON.parse');
};
}
})(
(typeof exports !== 'undefined') ?
exports :
(window.JSON ?
(window.JSON) :
(window.JSON = {})
)
);
},{}],4:[function(require,module,exports){
/**
* Expose `Emitter`.
*/
module.exports = Emitter;
/**
* Initialize a new `Emitter`.
*
* @api public
*/
function Emitter(obj) {
if (obj) return mixin(obj);
};
/**
* Mixin the emitter properties.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
}
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
(this._callbacks[event] = this._callbacks[event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
var self = this;
this._callbacks = this._callbacks || {};
function on() {
self.off(event, on);
fn.apply(this, arguments);
}
on.fn = fn;
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
var callbacks = this._callbacks[event];
if (!callbacks) return this;
if (1 == arguments.length) {
delete this._callbacks[event];
return this;
}
var cb;
for (var i = 0; i < callbacks.length; i++) {
cb = callbacks[i];
if (cb === fn || cb.fn === fn) {
callbacks.splice(i, 1);
break;
}
}
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = [].slice.call(arguments, 1)
, callbacks = this._callbacks[event];
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
/**
* Return array of callbacks for `event`.
*
* @param {String} event
* @return {Array}
* @api public
*/
Emitter.prototype.listeners = function(event){
this._callbacks = this._callbacks || {};
return this._callbacks[event] || [];
};
/**
* Check if this emitter has `event` handlers.
*
* @param {String} event
* @return {Boolean}
* @api public
*/
Emitter.prototype.hasListeners = function(event){
return !! this.listeners(event).length;
};
},{}],5:[function(require,module,exports){
/*!
* domready (c) Dustin Diaz 2012 - License MIT
*/
!function (name, definition) {
if (typeof module != 'undefined') module.exports = definition()
else if (typeof define == 'function' && typeof define.amd == 'object') define(definition)
else this[name] = definition()
}('domready', function (ready) {
var fns = [], fn, f = false
, doc = document
, testEl = doc.documentElement
, hack = testEl.doScroll
, domContentLoaded = 'DOMContentLoaded'
, addEventListener = 'addEventListener'
, onreadystatechange = 'onreadystatechange'
, readyState = 'readyState'
, loadedRgx = hack ? /^loaded|^c/ : /^loaded|c/
, loaded = loadedRgx.test(doc[readyState])
function flush(f) {
loaded = 1
while (f = fns.shift()) f()
}
doc[addEventListener] && doc[addEventListener](domContentLoaded, fn = function () {
doc.removeEventListener(domContentLoaded, fn, f)
flush()
}, f)
hack && doc.attachEvent(onreadystatechange, fn = function () {
if (/^c/.test(doc[readyState])) {
doc.detachEvent(onreadystatechange, fn)
flush()
}
})
return (ready = hack ?
function (fn) {
self != top ?
loaded ? fn() : fns.push(fn) :
function () {
try {
testEl.doScroll('left')
} catch (e) {
return setTimeout(function() { ready(fn) }, 50)
}
fn()
}()
} :
function (fn) {
loaded ? fn() : fns.push(fn)
})
})
},{}],6:[function(require,module,exports){
/**
* Module dependencies.
*/
var Emitter = require('emitter');
var reduce = require('reduce');
/**
* Root reference for iframes.
*/
var root = 'undefined' == typeof window
? this
: window;
/**
* Noop.
*/
function noop(){};
/**
* Check if `obj` is a host object,
* we don't want to serialize these :)
*
* TODO: future proof, move to compoent land
*
* @param {Object} obj
* @return {Boolean}
* @api private
*/
function isHost(obj) {
var str = {}.toString.call(obj);
switch (str) {
case '[object File]':
case '[object Blob]':
case '[object FormData]':
return true;
default:
return false;
}
}
/**
* Determine XHR.
*/
function getXHR() {
if (root.XMLHttpRequest
&& ('file:' != root.location.protocol || !root.ActiveXObject)) {
return new XMLHttpRequest;
} else {
try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
}
return false;
}
/**
* Removes leading and trailing whitespace, added to support IE.
*
* @param {String} s
* @return {String}
* @api private
*/
var trim = ''.trim
? function(s) { return s.trim(); }
: function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
/**
* Check if `obj` is an object.
*
* @param {Object} obj
* @return {Boolean}
* @api private
*/
function isObject(obj) {
return obj === Object(obj);
}
/**
* Serialize the given `obj`.
*
* @param {Object} obj
* @return {String}
* @api private
*/
function serialize(obj) {
if (!isObject(obj)) return obj;
var pairs = [];
for (var key in obj) {
if (null != obj[key]) {
pairs.push(encodeURIComponent(key)
+ '=' + encodeURIComponent(obj[key]));
}
}
return pairs.join('&');
}
/**
* Expose serialization method.
*/
request.serializeObject = serialize;
/**
* Parse the given x-www-form-urlencoded `str`.
*
* @param {String} str
* @return {Object}
* @api private
*/
function parseString(str) {
var obj = {};
var pairs = str.split('&');
var parts;
var pair;
for (var i = 0, len = pairs.length; i < len; ++i) {
pair = pairs[i];
parts = pair.split('=');
obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
}
return obj;
}
/**
* Expose parser.
*/
request.parseString = parseString;
/**
* Default MIME type map.
*
* superagent.types.xml = 'application/xml';
*
*/
request.types = {
html: 'text/html',
json: 'application/json',
xml: 'application/xml',
urlencoded: 'application/x-www-form-urlencoded',
'form': 'application/x-www-form-urlencoded',
'form-data': 'application/x-www-form-urlencoded'
};
/**
* Default serialization map.
*
* superagent.serialize['application/xml'] = function(obj){
* return 'generated xml here';
* };
*
*/
request.serialize = {
'application/x-www-form-urlencoded': serialize,
'application/json': JSON.stringify
};
/**
* Default parsers.
*
* superagent.parse['application/xml'] = function(str){
* return { object parsed from str };
* };
*
*/
request.parse = {
'application/x-www-form-urlencoded': parseString,
'application/json': JSON.parse
};
/**
* Parse the given header `str` into
* an object containing the mapped fields.
*
* @param {String} str
* @return {Object}
* @api private
*/
function parseHeader(str) {
var lines = str.split(/\r?\n/);
var fields = {};
var index;
var line;
var field;
var val;
lines.pop();
for (var i = 0, len = lines.length; i < len; ++i) {
line = lines[i];
index = line.indexOf(':');
field = line.slice(0, index).toLowerCase();
val = trim(line.slice(index + 1));
fields[field] = val;
}
return fields;
}
/**
* Return the mime type for the given `str`.
*
* @param {String} str
* @return {String}
* @api private
*/
function type(str){
return str.split(/ *; */).shift();
};
/**
* Return header field parameters.
*
* @param {String} str
* @return {Object}
* @api private
*/
function params(str){
return reduce(str.split(/ *; */), function(obj, str){
var parts = str.split(/ *= */)
, key = parts.shift()
, val = parts.shift();
if (key && val) obj[key] = val;
return obj;
}, {});
};
/**
* Initialize a new `Response` with the given `xhr`.
*
* - set flags (.ok, .error, etc)
* - parse header
*
* Examples:
*
* Aliasing `superagent` as `request` is nice:
*
* request = superagent;
*
* We can use the promise-like API, or pass callbacks:
*
* request.get('/').end(function(res){});
* request.get('/', function(res){});
*
* Sending data can be chained:
*
* request
* .post('/user')
* .send({ name: 'tj' })
* .end(function(res){});
*
* Or passed to `.send()`:
*
* request
* .post('/user')
* .send({ name: 'tj' }, function(res){});
*
* Or passed to `.post()`:
*
* request
* .post('/user', { name: 'tj' })
* .end(function(res){});
*
* Or further reduced to a single call for simple cases:
*
* request
* .post('/user', { name: 'tj' }, function(res){});
*
* @param {XMLHTTPRequest} xhr
* @param {Object} options
* @api private
*/
function Response(req, options) {
options = options || {};
this.req = req;
this.xhr = this.req.xhr;
this.text = this.req.method !='HEAD'
? this.xhr.responseText
: null;
this.setStatusProperties(this.xhr.status);
this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
this.header['content-type'] = this.xhr.getResponseHeader('content-type');
this.setHeaderProperties(this.header);
this.body = this.req.method != 'HEAD'
? this.parseBody(this.text)
: null;
}
/**
* Get case-insensitive `field` value.
*
* @param {String} field
* @return {String}
* @api public
*/
Response.prototype.get = function(field){
return this.header[field.toLowerCase()];
};
/**
* Set header related properties:
*
* - `.type` the content type without params
*
* A response of "Content-Type: text/plain; charset=utf-8"
* will provide you with a `.type` of "text/plain".
*
* @param {Object} header
* @api private
*/
Response.prototype.setHeaderProperties = function(header){
var ct = this.header['content-type'] || '';
this.type = type(ct);
var obj = params(ct);
for (var key in obj) this[key] = obj[key];
};
/**
* Parse the given body `str`.
*
* Used for auto-parsing of bodies. Parsers
* are defined on the `superagent.parse` object.
*
* @param {String} str
* @return {Mixed}
* @api private
*/
Response.prototype.parseBody = function(str){
var parse = request.parse[this.type];
return parse && str && str.length
? parse(str)
: null;
};
/**
* Set flags such as `.ok` based on `status`.
*
* For example a 2xx response will give you a `.ok` of __true__
* whereas 5xx will be __false__ and `.error` will be __true__. The
* `.clientError` and `.serverError` are also available to be more
* specific, and `.statusType` is the class of error ranging from 1..5
* sometimes useful for mapping respond colors etc.
*
* "sugar" properties are also defined for common cases. Currently providing:
*
* - .noContent
* - .badRequest
* - .unauthorized
* - .notAcceptable
* - .notFound
*
* @param {Number} status
* @api private
*/
Response.prototype.setStatusProperties = function(status){
var type = status / 100 | 0;
this.status = status;
this.statusType = type;
this.info = 1 == type;
this.ok = 2 == type;
this.clientError = 4 == type;
this.serverError = 5 == type;
this.error = (4 == type || 5 == type)
? this.toError()
: false;
this.accepted = 202 == status;
this.noContent = 204 == status || 1223 == status;
this.badRequest = 400 == status;
this.unauthorized = 401 == status;
this.notAcceptable = 406 == status;
this.notFound = 404 == status;
this.forbidden = 403 == status;
};
/**
* Return an `Error` representative of this response.
*
* @return {Error}
* @api public
*/
Response.prototype.toError = function(){
var req = this.req;
var method = req.method;
var url = req.url;
var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
var err = new Error(msg);
err.status = this.status;
err.method = method;
err.url = url;
return err;
};
/**
* Expose `Response`.
*/
request.Response = Response;
/**
* Initialize a new `Request` with the given `method` and `url`.
*
* @param {String} method
* @param {String} url
* @api public
*/
function Request(method, url) {
var self = this;
Emitter.call(this);
this._query = this._query || [];
this.method = method;
this.url = url;
this.header = {};
this._header = {};
this.on('end', function(){
var err = null;
var res = null;
try {
res = new Response(self);
} catch(e) {
err = new Error('Parser is unable to parse the response');
err.parse = true;
err.original = e;
}
self.callback(err, res);
});
}
/**
* Mixin `Emitter`.
*/
Emitter(Request.prototype);
/**
* Allow for extension
*/
Request.prototype.use = function(fn) {
fn(this);
return this;
}
/**
* Set timeout to `ms`.
*
* @param {Number} ms
* @return {Request} for chaining
* @api public
*/
Request.prototype.timeout = function(ms){
this._timeout = ms;
return this;
};
/**
* Clear previous timeout.
*
* @return {Request} for chaining
* @api public
*/
Request.prototype.clearTimeout = function(){
this._timeout = 0;
clearTimeout(this._timer);
return this;
};
/**
* Abort the request, and clear potential timeout.
*
* @return {Request}
* @api public
*/
Request.prototype.abort = function(){
if (this.aborted) return;
this.aborted = true;
this.xhr.abort();
this.clearTimeout();
this.emit('abort');
return this;
};
/**
* Set header `field` to `val`, or multiple fields with one object.
*
* Examples:
*
* req.get('/')
* .set('Accept', 'application/json')
* .set('X-API-Key', 'foobar')
* .end(callback);
*
* req.get('/')
* .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
* .end(callback);
*
* @param {String|Object} field
* @param {String} val
* @return {Request} for chaining
* @api public
*/
Request.prototype.set = function(field, val){
if (isObject(field)) {
for (var key in field) {
this.set(key, field[key]);
}
return this;
}
this._header[field.toLowerCase()] = val;
this.header[field] = val;
return this;
};
/**
* Remove header `field`.
*
* Example:
*
* req.get('/')
* .unset('User-Agent')
* .end(callback);
*
* @param {String} field
* @return {Request} for chaining
* @api public
*/
Request.prototype.unset = function(field){
delete this._header[field.toLowerCase()];
delete this.header[field];
return this;
};
/**
* Get case-insensitive header `field` value.
*
* @param {String} field
* @return {String}
* @api private
*/
Request.prototype.getHeader = function(field){
return this._header[field.toLowerCase()];
};
/**
* Set Content-Type to `type`, mapping values from `request.types`.
*
* Examples:
*
* superagent.types.xml = 'application/xml';
*
* request.post('/')
* .type('xml')
* .send(xmlstring)
* .end(callback);
*
* request.post('/')
* .type('application/xml')
* .send(xmlstring)
* .end(callback);
*
* @param {String} type
* @return {Request} for chaining
* @api public
*/
Request.prototype.type = function(type){
this.set('Content-Type', request.types[type] || type);
return this;
};
/**
* Set Accept to `type`, mapping values from `request.types`.
*
* Examples:
*
* superagent.types.json = 'application/json';
*
* request.get('/agent')
* .accept('json')
* .end(callback);
*
* request.get('/agent')
* .accept('application/json')
* .end(callback);
*
* @param {String} accept
* @return {Request} for chaining
* @api public
*/
Request.prototype.accept = function(type){
this.set('Accept', request.types[type] || type);
return this;
};
/**
* Set Authorization field value with `user` and `pass`.
*
* @param {String} user
* @param {String} pass
* @return {Request} for chaining
* @api public
*/
Request.prototype.auth = function(user, pass){
var str = btoa(user + ':' + pass);
this.set('Authorization', 'Basic ' + str);
return this;
};
/**
* Add query-string `val`.
*
* Examples:
*
* request.get('/shoes')
* .query('size=10')
* .query({ color: 'blue' })
*
* @param {Object|String} val
* @return {Request} for chaining
* @api public
*/
Request.prototype.query = function(val){
if ('string' != typeof val) val = serialize(val);
if (val) this._query.push(val);
return this;
};
/**
* Write the field `name` and `val` for "multipart/form-data"
* request bodies.
*
* ``` js
* request.post('/upload')
* .field('foo', 'bar')
* .end(callback);
* ```
*
* @param {String} name
* @param {String|Blob|File} val
* @return {Request} for chaining
* @api public
*/
Request.prototype.field = function(name, val){
if (!this._formData) this._formData = new FormData();
this._formData.append(name, val);
return this;
};
/**
* Queue the given `file` as an attachment to the specified `field`,
* with optional `filename`.
*
* ``` js
* request.post('/upload')
* .attach(new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
* .end(callback);
* ```
*
* @param {String} field
* @param {Blob|File} file
* @param {String} filename
* @return {Request} for chaining
* @api public
*/
Request.prototype.attach = function(field, file, filename){
if (!this._formData) this._formData = new FormData();
this._formData.append(field, file, filename);
return this;
};
/**
* Send `data`, defaulting the `.type()` to "json" when
* an object is given.
*
* Examples:
*
*
* request.get('/search')
* .end(callback)
*
*
* request.get('/search')
* .send({ search: 'query' })
* .send({ range: '1..5' })
* .send({ order: 'desc' })
* .end(callback)
*
*
* request.post('/user')
* .type('json')
* .send('{"name":"tj"})
* .end(callback)
*
*
* request.post('/user')
* .send({ name: 'tj' })
* .end(callback)
*
*
* request.post('/user')
* .type('form')
* .send('name=tj')
* .end(callback)
*
*
* request.post('/user')
* .type('form')
* .send({ name: 'tj' })
* .end(callback)
*
*
* request.post('/user')
* .send('name=tobi')
* .send('species=ferret')
* .end(callback)
*
* @param {String|Object} data
* @return {Request} for chaining
* @api public
*/
Request.prototype.send = function(data){
var obj = isObject(data);
var type = this.getHeader('Content-Type');
if (obj && isObject(this._data)) {
for (var key in data) {
this._data[key] = data[key];
}
} else if ('string' == typeof data) {
if (!type) this.type('form');
type = this.getHeader('Content-Type');
if ('application/x-www-form-urlencoded' == type) {
this._data = this._data
? this._data + '&' + data
: data;
} else {
this._data = (this._data || '') + data;
}
} else {
this._data = data;
}
if (!obj) return this;
if (!type) this.type('json');
return this;
};
/**
* Invoke the callback with `err` and `res`
* and handle arity check.
*
* @param {Error} err
* @param {Response} res
* @api private
*/
Request.prototype.callback = function(err, res){
var fn = this._callback;
this.clearTimeout();
if (2 == fn.length) return fn(err, res);
if (err) return this.emit('error', err);
fn(res);
};
/**
* Invoke callback with x-domain error.
*
* @api private
*/
Request.prototype.crossDomainError = function(){
var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');
err.crossDomain = true;
this.callback(err);
};
/**
* Invoke callback with timeout error.
*
* @api private
*/
Request.prototype.timeoutError = function(){
var timeout = this._timeout;
var err = new Error('timeout of ' + timeout + 'ms exceeded');
err.timeout = timeout;
this.callback(err);
};
/**
* Enable transmission of cookies with x-domain requests.
*
* Note that for this to work the origin must not be
* using "Access-Control-Allow-Origin" with a wildcard,
* and also must set "Access-Control-Allow-Credentials"
* to "true".
*
* @api public
*/
Request.prototype.withCredentials = function(){
this._withCredentials = true;
return this;
};
/**
* Initiate request, invoking callback `fn(res)`
* with an instanceof `Response`.
*
* @param {Function} fn
* @return {Request} for chaining
* @api public
*/
Request.prototype.end = function(fn){
var self = this;
var xhr = this.xhr = getXHR();
var query = this._query.join('&');
var timeout = this._timeout;
var data = this._formData || this._data;
this._callback = fn || noop;
xhr.onreadystatechange = function(){
if (4 != xhr.readyState) return;
if (0 == xhr.status) {
if (self.aborted) return self.timeoutError();
return self.crossDomainError();
}
self.emit('end');
};
if (xhr.upload) {
xhr.upload.onprogress = function(e){
e.percent = e.loaded / e.total * 100;
self.emit('progress', e);
};
}
if (timeout && !this._timer) {
this._timer = setTimeout(function(){
self.abort();
}, timeout);
}
if (query) {
query = request.serializeObject(query);
this.url += ~this.url.indexOf('?')
? '&' + query
: '?' + query;
}
xhr.open(this.method, this.url, true);
if (this._withCredentials) xhr.withCredentials = true;
if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
var serialize = request.serialize[this.getHeader('Content-Type')];
if (serialize) data = serialize(data);
}
for (var field in this.header) {
if (null == this.header[field]) continue;
xhr.setRequestHeader(field, this.header[field]);
}
this.emit('request', this);
xhr.send(data);
return this;
};
/**
* Expose `Request`.
*/
request.Request = Request;
/**
* Issue a request:
*
* Examples:
*
* request('GET', '/users').end(callback)
* request('/users').end(callback)
* request('/users', callback)
*
* @param {String} method
* @param {String|Function} url or callback
* @return {Request}
* @api public
*/
function request(method, url) {
if ('function' == typeof url) {
return new Request('GET', method).end(url);
}
if (1 == arguments.length) {
return new Request('GET', method);
}
return new Request(method, url);
}
/**
* GET `url` with optional callback `fn(res)`.
*
* @param {String} url
* @param {Mixed|Function} data or fn
* @param {Function} fn
* @return {Request}
* @api public
*/
request.get = function(url, data, fn){
var req = request('GET', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.query(data);
if (fn) req.end(fn);
return req;
};
/**
* HEAD `url` with optional callback `fn(res)`.
*
* @param {String} url
* @param {Mixed|Function} data or fn
* @param {Function} fn
* @return {Request}
* @api public
*/
request.head = function(url, data, fn){
var req = request('HEAD', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* DELETE `url` with optional callback `fn(res)`.
*
* @param {String} url
* @param {Function} fn
* @return {Request}
* @api public
*/
request.del = function(url, fn){
var req = request('DELETE', url);
if (fn) req.end(fn);
return req;
};
/**
* PATCH `url` with optional `data` and callback `fn(res)`.
*
* @param {String} url
* @param {Mixed} data
* @param {Function} fn
* @return {Request}
* @api public
*/
request.patch = function(url, data, fn){
var req = request('PATCH', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* POST `url` with optional `data` and callback `fn(res)`.
*
* @param {String} url
* @param {Mixed} data
* @param {Function} fn
* @return {Request}
* @api public
*/
request.post = function(url, data, fn){
var req = request('POST', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* PUT `url` with optional `data` and callback `fn(res)`.
*
* @param {String} url
* @param {Mixed|Function} data or fn
* @param {Function} fn
* @return {Request}
* @api public
*/
request.put = function(url, data, fn){
var req = request('PUT', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* Expose `request`.
*/
module.exports = request;
},{"emitter":7,"reduce":8}],7:[function(require,module,exports){
arguments[4][4][0].apply(exports,arguments)
},{"dup":4}],8:[function(require,module,exports){
/**
* Reduce `arr` with `fn`.
*
* @param {Array} arr
* @param {Function} fn
* @param {Mixed} initial
*
* TODO: combatible error handling?
*/
module.exports = function(arr, fn, initial){
var idx = 0;
var len = arr.length;
var curr = arguments.length == 3
? initial
: arr[idx++];
while (idx < len) {
curr = fn.call(null, curr, arr[idx], ++idx, arr);
}
return curr;
};
},{}],9:[function(require,module,exports){
var Keen = require("./index"),
each = require("./utils/each");
module.exports = function(){
var loaded = window['Keen'] || null,
cached = window['_' + 'Keen'] || null,
clients,
ready;
if (loaded && cached) {
clients = cached['clients'] || {},
ready = cached['ready'] || [];
each(clients, function(client, id){
each(Keen.prototype, function(method, key){
loaded.prototype[key] = method;
});
each(["Query", "Request", "Dataset", "Dataviz"], function(name){
loaded[name] = (Keen[name]) ? Keen[name] : function(){};
});
if (client._config) {
client.configure.call(client, client._config);
}
if (client._setGlobalProperties) {
each(client._setGlobalProperties, function(fn){
client.setGlobalProperties.apply(client, fn);
});
}
if (client._addEvent) {
each(client._addEvent, function(obj){
client.addEvent.apply(client, obj);
});
}
var callback = client._on || [];
if (client._on) {
each(client._on, function(obj){
client.on.apply(client, obj);
});
client.trigger('ready');
}
each(["_config", "_setGlobalProperties", "_addEvent", "_on"], function(name){
if (client[name]) {
client[name] = undefined;
try{
delete client[name];
} catch(e){}
}
});
});
each(ready, function(cb, i){
Keen.once("ready", cb);
});
}
window['_' + 'Keen'] = undefined;
try {
delete window['_' + 'Keen']
} catch(e) {}
};
},{"./index":17,"./utils/each":23}],10:[function(require,module,exports){
var Emitter = require('component-emitter');
Emitter.prototype.trigger = Emitter.prototype.emit;
module.exports = Emitter;
},{"component-emitter":4}],11:[function(require,module,exports){
module.exports = function(){
return "undefined" == typeof window ? "server" : "browser";
};
},{}],12:[function(require,module,exports){
var each = require('../utils/each'),
JSON2 = require('JSON2');
module.exports = function(params){
var query = [];
each(params, function(value, key){
if ('string' !== typeof value) {
value = JSON2.stringify(value);
}
query.push(key + '=' + encodeURIComponent(value));
});
return '?' + query.join('&');
};
},{"../utils/each":23,"JSON2":2}],13:[function(require,module,exports){
module.exports = function(){
if ("undefined" !== typeof window) {
if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) {
return 2000;
}
}
return 16000;
};
},{}],14:[function(require,module,exports){
module.exports = function() {
var root = "undefined" == typeof window ? this : window;
if (root.XMLHttpRequest && ("file:" != root.location.protocol || !root.ActiveXObject)) {
return new XMLHttpRequest;
} else {
try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
}
return false;
};
},{}],15:[function(require,module,exports){
module.exports = function(err, res, callback) {
var cb = callback || function() {};
if (res && !res.ok) {
var is_err = res.body && res.body.error_code;
err = new Error(is_err ? res.body.message : 'Unknown error occurred');
err.code = is_err ? res.body.error_code : 'UnknownError';
}
if (err) {
cb(err, null);
}
else {
cb(null, res.body);
}
return;
};
},{}],16:[function(require,module,exports){
var superagent = require('superagent');
var each = require('../utils/each'),
getXHR = require('./get-xhr-object');
module.exports = function(type, opts){
return function(request) {
var __super__ = request.constructor.prototype.end;
if ( 'undefined' === typeof window ) return;
request.requestType = request.requestType || {};
request.requestType['type'] = type;
request.requestType['options'] = request.requestType['options'] || {
async: true,
success: {
responseText: '{ "created": true }',
status: 201
},
error: {
responseText: '{ "error_code": "ERROR", "message": "Request failed" }',
status: 404
}
};
if (opts) {
if ( 'boolean' === typeof opts.async ) {
request.requestType['options'].async = opts.async;
}
if ( opts.success ) {
extend(request.requestType['options'].success, opts.success);
}
if ( opts.error ) {
extend(request.requestType['options'].error, opts.error);
}
}
request.end = function(fn){
var self = this,
reqType = (this.requestType) ? this.requestType['type'] : 'xhr',
query,
timeout;
if ( ('GET' !== self['method'] || 'xhr' === reqType) && self.requestType['options'].async ) {
__super__.call(self, fn);
return;
}
query = self._query.join('&');
timeout = self._timeout;
self._callback = fn || noop;
if (timeout && !self._timer) {
self._timer = setTimeout(function(){
abortRequest.call(self);
}, timeout);
}
if (query) {
query = superagent.serializeObject(query);
self.url += ~self.url.indexOf('?') ? '&' + query : '?' + query;
}
self.emit('request', self);
if ( !self.requestType['options'].async ) {
sendXhrSync.call(self);
}
else if ( 'jsonp' === reqType ) {
sendJsonp.call(self);
}
else if ( 'beacon' === reqType ) {
sendBeacon.call(self);
}
return self;
};
return request;
};
};
function sendXhrSync(){
var xhr = getXHR();
if (xhr) {
xhr.open('GET', this.url, false);
xhr.send(null);
}
return this;
}
function sendJsonp(){
var self = this,
timestamp = new Date().getTime(),
script = document.createElement('script'),
parent = document.getElementsByTagName('head')[0],
callbackName = 'keenJSONPCallback',
loaded = false;
callbackName += timestamp;
while (callbackName in window) {
callbackName += 'a';
}
window[callbackName] = function(response) {
if (loaded === true) return;
loaded = true;
handleSuccess.call(self, response);
cleanup();
};
script.src = self.url + '&jsonp=' + callbackName;
parent.appendChild(script);
script.onreadystatechange = function() {
if (loaded === false && self.readyState === 'loaded') {
loaded = true;
handleError.call(self);
cleanup();
}
};
script.onerror = function() {
if (loaded === false) {
loaded = true;
handleError.call(self);
cleanup();
}
};
function cleanup(){
window[callbackName] = undefined;
try {
delete window[callbackName];
} catch(e){}
parent.removeChild(script);
}
}
function sendBeacon(){
var self = this,
img = document.createElement('img'),
loaded = false;
img.onload = function() {
loaded = true;
if ('naturalHeight' in this) {
if (this.naturalHeight + this.naturalWidth === 0) {
this.onerror();
return;
}
} else if (this.width + this.height === 0) {
this.onerror();
return;
}
handleSuccess.call(self);
};
img.onerror = function() {
loaded = true;
handleError.call(self);
};
img.src = self.url + '&c=clv1';
}
function handleSuccess(res){
var opts = this.requestType['options']['success'],
response = '';
xhrShim.call(this, opts);
if (res) {
try {
response = JSON.stringify(res);
} catch(e) {}
}
else {
response = opts['responseText'];
}
this.xhr.responseText = response;
this.xhr.status = opts['status'];
this.emit('end');
}
function handleError(){
var opts = this.requestType['options']['error'];
xhrShim.call(this, opts);
this.xhr.responseText = opts['responseText'];
this.xhr.status = opts['status'];
this.emit('end');
}
function abortRequest(){
this.aborted = true;
this.clearTimeout();
this.emit('abort');
}
function xhrShim(opts){
this.xhr = {
getAllResponseHeaders: function(){ return ''; },
getResponseHeader: function(){ return 'application/json'; },
responseText: opts['responseText'],
status: opts['status']
};
return this;
}
},{"../utils/each":23,"./get-xhr-object":14,"superagent":6}],17:[function(require,module,exports){
var root = this;
var previous_Keen = root.Keen;
var extend = require('./utils/extend');
var Emitter = require('./helpers/emitter-shim');
function Keen(config) {
this.configure(config || {});
Keen.trigger('client', this);
}
Keen.debug = false;
Keen.enabled = true;
Keen.loaded = true;
Keen.version = '3.2.1';
Emitter(Keen);
Emitter(Keen.prototype);
Keen.prototype.configure = function(cfg){
var config = cfg || {};
if (config['host']) {
config['host'].replace(/.*?:\/\//g, '');
}
if (config.protocol && config.protocol === 'auto') {
config['protocol'] = location.protocol.replace(/:/g, '');
}
this.config = {
projectId : config.projectId,
writeKey : config.writeKey,
readKey : config.readKey,
masterKey : config.masterKey,
requestType : config.requestType || 'jsonp',
host : config['host'] || 'api.keen.io/3.0',
protocol : config['protocol'] || 'https',
globalProperties: null
};
if (Keen.debug) {
this.on('error', Keen.log);
}
this.trigger('ready');
};
Keen.prototype.projectId = function(str){
if (!arguments.length) return this.config.projectId;
this.config.projectId = (str ? String(str) : null);
return this;
};
Keen.prototype.masterKey = function(str){
if (!arguments.length) return this.config.masterKey;
this.config.masterKey = (str ? String(str) : null);
return this;
};
Keen.prototype.readKey = function(str){
if (!arguments.length) return this.config.readKey;
this.config.readKey = (str ? String(str) : null);
return this;
};
Keen.prototype.writeKey = function(str){
if (!arguments.length) return this.config.writeKey;
this.config.writeKey = (str ? String(str) : null);
return this;
};
Keen.prototype.url = function(path){
if (!this.projectId()) {
this.trigger('error', 'Client is missing projectId property');
return;
}
return this.config.protocol + '://' + this.config.host + '/projects/' + this.projectId() + path;
};
Keen.log = function(message) {
if (Keen.debug && typeof console == 'object') {
console.log('[Keen IO]', message);
}
};
Keen.noConflict = function(){
root.Keen = previous_Keen;
return Keen;
};
Keen.ready = function(fn){
if (Keen.loaded) {
fn();
} else {
Keen.once('ready', fn);
}
};
module.exports = Keen;
},{"./helpers/emitter-shim":10,"./utils/extend":24}],18:[function(require,module,exports){
var JSON2 = require('JSON2');
var request = require('superagent');
var Keen = require('../index');
var base64 = require('../utils/base64'),
each = require('../utils/each'),
getContext = require('../helpers/get-context'),
getQueryString = require('../helpers/get-query-string'),
getUrlMaxLength = require('../helpers/get-url-max-length'),
getXHR = require('../helpers/get-xhr-object'),
requestTypes = require('../helpers/superagent-request-types'),
responseHandler = require('../helpers/superagent-handle-response');
module.exports = function(collection, payload, callback, async) {
var self = this,
urlBase = this.url('/events/' + collection),
reqType = this.config.requestType,
data = {},
cb = callback,
isAsync,
getUrl;
isAsync = ('boolean' === typeof async) ? async : true;
if (!Keen.enabled) {
handleValidationError.call(self, 'Keen.enabled = false');
return;
}
if (!self.projectId()) {
handleValidationError.call(self, 'Missing projectId property');
return;
}
if (!self.writeKey()) {
handleValidationError.call(self, 'Missing writeKey property');
return;
}
if (!collection || typeof collection !== 'string') {
handleValidationError.call(self, 'Collection name must be a string');
return;
}
if (self.config.globalProperties) {
data = self.config.globalProperties(collection);
}
each(payload, function(value, key){
data[key] = value;
});
if ( !getXHR() && 'xhr' === reqType ) {
reqType = 'jsonp';
}
if ( 'xhr' !== reqType || !isAsync ) {
getUrl = prepareGetRequest.call(self, urlBase, data);
}
if ( getUrl && getContext() === 'browser' ) {
request
.get(getUrl)
.use(function(req){
req.async = isAsync;
return req;
})
.use(requestTypes(reqType))
.end(handleResponse);
}
else if ( getXHR() || getContext() === 'server' ) {
request
.post(urlBase)
.set('Content-Type', 'application/json')
.set('Authorization', self.writeKey())
.send(data)
.end(handleResponse);
}
else {
self.trigger('error', 'Request not sent: URL length exceeds current browser limit, and XHR (POST) is not supported.');
}
function handleResponse(err, res){
responseHandler(err, res, cb);
cb = callback = null;
}
function handleValidationError(msg){
var err = 'Event not recorded: ' + msg;
self.trigger('error', err);
if (cb) {
cb.call(self, err, null);
cb = callback = null;
}
}
return;
};
function prepareGetRequest(url, data){
url += getQueryString({
api_key : this.writeKey(),
data : base64.encode( JSON2.stringify(data) ),
modified : new Date().getTime()
});
return ( url.length < getUrlMaxLength() ) ? url : false;
}
},{"../helpers/get-context":11,"../helpers/get-query-string":12,"../helpers/get-url-max-length":13,"../helpers/get-xhr-object":14,"../helpers/superagent-handle-response":15,"../helpers/superagent-request-types":16,"../index":17,"../utils/base64":22,"../utils/each":23,"JSON2":2,"superagent":6}],19:[function(require,module,exports){
var Keen = require('../index');
var request = require('superagent');
var each = require('../utils/each'),
getContext = require('../helpers/get-context'),
getXHR = require('../helpers/get-xhr-object'),
requestTypes = require('../helpers/superagent-request-types'),
responseHandler = require('../helpers/superagent-handle-response');
module.exports = function(payload, callback) {
var self = this,
urlBase = this.url('/events'),
data = {},
cb = callback;
if (!Keen.enabled) {
handleValidationError.call(self, 'Keen.enabled = false');
return;
}
if (!self.projectId()) {
handleValidationError.call(self, 'Missing projectId property');
return;
}
if (!self.writeKey()) {
handleValidationError.call(self, 'Missing writeKey property');
return;
}
if (arguments.length > 2) {
handleValidationError.call(self, 'Incorrect arguments provided to #addEvents method');
return;
}
if (typeof payload !== 'object' || payload instanceof Array) {
handleValidationError.call(self, 'Request payload must be an object');
return;
}
if (self.config.globalProperties) {
each(payload, function(events, collection){
each(events, function(body, index){
var base = self.config.globalProperties(collection);
each(body, function(value, key){
base[key] = value;
});
data[collection].push(base);
});
});
}
else {
data = payload;
}
if ( getXHR() || getContext() === 'server' ) {
request
.post(urlBase)
.set('Content-Type', 'application/json')
.set('Authorization', self.writeKey())
.send(data)
.end(function(err, res){
responseHandler(err, res, cb);
cb = callback = null;
});
}
else {
self.trigger('error', 'Events not recorded: XHR support is required for batch upload');
}
function handleValidationError(msg){
var err = 'Events not recorded: ' + msg;
self.trigger('error', err);
if (cb) {
cb.call(self, err, null);
cb = callback = null;
}
}
return;
};
},{"../helpers/get-context":11,"../helpers/get-xhr-object":14,"../helpers/superagent-handle-response":15,"../helpers/superagent-request-types":16,"../index":17,"../utils/each":23,"superagent":6}],20:[function(require,module,exports){
module.exports = function(newGlobalProperties) {
if (newGlobalProperties && typeof(newGlobalProperties) == "function") {
this.config.globalProperties = newGlobalProperties;
} else {
this.trigger("error", "Invalid value for global properties: " + newGlobalProperties);
}
};
},{}],21:[function(require,module,exports){
var addEvent = require("./addEvent");
module.exports = function(jsEvent, eventCollection, payload, timeout, timeoutCallback){
var evt = jsEvent,
target = (evt.currentTarget) ? evt.currentTarget : (evt.srcElement || evt.target),
timer = timeout || 500,
triggered = false,
targetAttr = "",
callback,
win;
if (target.getAttribute !== void 0) {
targetAttr = target.getAttribute("target");
} else if (target.target) {
targetAttr = target.target;
}
if ((targetAttr == "_blank" || targetAttr == "blank") && !evt.metaKey) {
win = window.open("about:blank");
win.document.location = target.href;
}
if (target.nodeName === "A") {
callback = function(){
if(!triggered && !evt.metaKey && (targetAttr !== "_blank" && targetAttr !== "blank")){
triggered = true;
window.location = target.href;
}
};
} else if (target.nodeName === "FORM") {
callback = function(){
if(!triggered){
triggered = true;
target.submit();
}
};
} else {
this.trigger("error", "#trackExternalLink method not attached to an <a> or <form> DOM element");
}
if (timeoutCallback) {
callback = function(){
if(!triggered){
triggered = true;
timeoutCallback();
}
};
}
addEvent.call(this, eventCollection, payload, callback);
setTimeout(callback, timer);
if (!evt.metaKey) {
return false;
}
};
},{"./addEvent":18}],22:[function(require,module,exports){
module.exports = {
map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function (n) {
"use strict";
var o = "", i = 0, m = this.map, i1, i2, i3, e1, e2, e3, e4;
n = this.utf8.encode(n);
while (i < n.length) {
i1 = n.charCodeAt(i++); i2 = n.charCodeAt(i++); i3 = n.charCodeAt(i++);
e1 = (i1 >> 2); e2 = (((i1 & 3) << 4) | (i2 >> 4)); e3 = (isNaN(i2) ? 64 : ((i2 & 15) << 2) | (i3 >> 6));
e4 = (isNaN(i2) || isNaN(i3)) ? 64 : i3 & 63;
o = o + m.charAt(e1) + m.charAt(e2) + m.charAt(e3) + m.charAt(e4);
} return o;
},
decode: function (n) {
"use strict";
var o = "", i = 0, m = this.map, cc = String.fromCharCode, e1, e2, e3, e4, c1, c2, c3;
n = n.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < n.length) {
e1 = m.indexOf(n.charAt(i++)); e2 = m.indexOf(n.charAt(i++));
e3 = m.indexOf(n.charAt(i++)); e4 = m.indexOf(n.charAt(i++));
c1 = (e1 << 2) | (e2 >> 4); c2 = ((e2 & 15) << 4) | (e3 >> 2);
c3 = ((e3 & 3) << 6) | e4;
o = o + (cc(c1) + ((e3 != 64) ? cc(c2) : "")) + (((e4 != 64) ? cc(c3) : ""));
} return this.utf8.decode(o);
},
utf8: {
encode: function (n) {
"use strict";
var o = "", i = 0, cc = String.fromCharCode, c;
while (i < n.length) {
c = n.charCodeAt(i++); o = o + ((c < 128) ? cc(c) : ((c > 127) && (c < 2048)) ?
(cc((c >> 6) | 192) + cc((c & 63) | 128)) : (cc((c >> 12) | 224) + cc(((c >> 6) & 63) | 128) + cc((c & 63) | 128)));
} return o;
},
decode: function (n) {
"use strict";
var o = "", i = 0, cc = String.fromCharCode, c2, c;
while (i < n.length) {
c = n.charCodeAt(i);
o = o + ((c < 128) ? [cc(c), i++][0] : ((c > 191) && (c < 224)) ?
[cc(((c & 31) << 6) | ((c2 = n.charCodeAt(i + 1)) & 63)), (i += 2)][0] :
[cc(((c & 15) << 12) | (((c2 = n.charCodeAt(i + 1)) & 63) << 6) | ((c3 = n.charCodeAt(i + 2)) & 63)), (i += 3)][0]);
} return o;
}
}
};
},{}],23:[function(require,module,exports){
module.exports = function(o, cb, s){
var n;
if (!o){
return 0;
}
s = !s ? o : s;
if (o instanceof Array){
for (n=0; n<o.length; n++) {
if (cb.call(s, o[n], n, o) === false){
return 0;
}
}
} else {
for (n in o){
if (o.hasOwnProperty(n)) {
if (cb.call(s, o[n], n, o) === false){
return 0;
}
}
}
}
return 1;
};
},{}],24:[function(require,module,exports){
module.exports = function(target){
for (var i = 1; i < arguments.length; i++) {
for (var prop in arguments[i]){
target[prop] = arguments[i][prop];
}
}
return target;
};
},{}],25:[function(require,module,exports){
function parseParams(str){
var urlParams = {},
match,
pl = /\+/g,
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
query = str.split("?")[1];
while (!!(match=search.exec(query))) {
urlParams[decode(match[1])] = decode(match[2]);
}
return urlParams;
};
module.exports = parseParams;
},{}],26:[function(require,module,exports){
(function (global){
;(function (f) {
if (typeof define === "function" && define.amd) {
define("keen", [], function(){ return f(); });
}
if (typeof exports === "object" && typeof module !== "undefined") {
module.exports = f();
}
var g = null;
if (typeof window !== "undefined") {
g = window;
} else if (typeof global !== "undefined") {
g = global;
} else if (typeof self !== "undefined") {
g = self;
}
if (g) {
g.Keen = f();
}
})(function() {
"use strict";
var Keen = require("./core"),
extend = require("./core/utils/extend");
extend(Keen.prototype, {
"addEvent" : require("./core/lib/addEvent"),
"addEvents" : require("./core/lib/addEvents"),
"setGlobalProperties" : require("./core/lib/setGlobalProperties"),
"trackExternalLink" : require("./core/lib/trackExternalLink")
});
Keen.Base64 = require("./core/utils/base64");
Keen.utils = {
"domready" : require("domready"),
"each" : require("./core/utils/each"),
"extend" : extend,
"parseParams" : require("./core/utils/parseParams")
};
if (Keen.loaded) {
setTimeout(function(){
Keen.utils.domready(function(){
Keen.emit("ready");
});
}, 0);
}
require("./core/async")();
module.exports = Keen;
return Keen;
});
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./core":17,"./core/async":9,"./core/lib/addEvent":18,"./core/lib/addEvents":19,"./core/lib/setGlobalProperties":20,"./core/lib/trackExternalLink":21,"./core/utils/base64":22,"./core/utils/each":23,"./core/utils/extend":24,"./core/utils/parseParams":25,"domready":5}]},{},[26]);