<commit_before>;(function(exports){
    var D = function(a){function b(a){j(function(){throw a})}function c(b){return this.then(b,a)}function d(b){return this.then(a,b)}function e(b,c){return this.then(function(a){return k(b)?b.apply(null,l(a)?a:[a]):t.onlyFuncs?a:b},c||a)}function f(a){function b(){a()}return this.then(b,b),this}function g(a){return this.then(function(b){return k(a)?a.apply(null,l(b)?b.splice(0,0,void 0)&&b:[void 0,b]):t.onlyFuncs?b:a},function(b){return a(b)})}function h(c){return this.then(a,c?function(a){throw c(a),a}:b)}function i(a,b){var c=o(a);if(1===c.length&&l(c[0])){if(!c[0].length)return t.fulfilled([]);c=c[0]}var d=[],e=t(),f=c.length;if(f)for(var g=(function(a){c[a]=t.promisify(c[a]),c[a].then(function(g){a in d||(d[a]=b?c[a]:g,--f||e.resolve(d))},function(g){a in d||(b?(d[a]=c[a],--f||e.resolve(d)):e.reject(g))})}),h=0,i=f;i>h;h++)g(h);else e.resolve(d);return e.promise}var j,k=function(a){return"function"==typeof a},l=function(a){return Array.isArray?Array.isArray(a):a instanceof Array},m=function(a){return!(!a||!(typeof a).match(/function|object/))},n=function(b){return b===!1||b===a||null===b},o=function(a,b){return[].slice.call(a,b)},p="undefined",q=typeof TypeError===p?Error:TypeError;if(typeof process!==p&&process.nextTick)j=process.nextTick;else if(typeof MessageChannel!==p){var r=new MessageChannel,s=[];r.port1.onmessage=function(){s.length&&s.shift()()},j=function(a){s.push(a),r.port2.postMessage(0)}}else j=function(a){setTimeout(a,0)};var t=function(b){function i(){if(0!==s){var a,b=u,c=0,d=b.length,e=~s?0:1;for(u=[];d>c;c++)(a=b[c][e])&&a(p)}}function l(a){function b(a){return function(b){return c?void 0:(c=!0,a(b))}}var c=!1;if(s)return this;try{var d=m(a)&&a.then;if(k(d)){if(a===v)throw new q("Promise can't resolve itself");return d.call(a,b(l),b(o)),this}}catch(e){return b(o)(e),this}return r(function(){p=a,s=1,i()}),this}function o(a){return s||r(function(){try{throw a}catch(b){p=b}s=-1,i()}),this}var p,r=(a!==b?b:t.alwaysAsync)?j:function(a){a()},s=0,u=[],v={then:function(a,b){var c=t();return u.push([function(b){try{n(a)?c.resolve(b):c.resolve(k(a)?a(b):t.onlyFuncs?b:a)}catch(d){c.reject(d)}},function(a){if((n(b)||!k(b)&&t.onlyFuncs)&&c.reject(a),b)try{c.resolve(k(b)?b(a):b)}catch(d){c.reject(d)}}]),0!==s&&r(i),c.promise},success:c,error:d,otherwise:d,apply:e,spread:e,ensure:f,nodify:g,rethrow:h,isPending:function(){return!(0!==s)},getStatus:function(){return s}};return v.toSource=v.toString=v.valueOf=function(){return p===a?this:p},{promise:v,resolve:l,fulfill:l,reject:o}};t.deferred=t.defer=t,t.nextTick=j,t.alwaysAsync=!0,t.onlyFuncs=!0,t.resolved=t.fulfilled=function(a){return t(!0).resolve(a).promise},t.rejected=function(a){return t(!0).reject(a).promise},t.wait=function(a){var b=t();return setTimeout(b.resolve,a||0),b.promise},t.delay=function(a,b){var c=t();return setTimeout(function(){try{c.resolve(a.apply(null))}catch(b){c.reject(b)}},b||0),c.promise},t.promisify=function(a){return a&&k(a.then)?a:t.resolved(a)},t.all=function(){return i(arguments,!1)},t.resolveAll=function(){return i(arguments,!0)},t.nodeCapsule=function(a,b){return b||(b=a,a=void 0),function(){var c=t(),d=o(arguments);d.push(function(a,b){a?c.reject(a):c.resolve(arguments.length>2?o(arguments,1):b)});try{b.apply(a,d)}catch(e){c.reject(e)}return c.promise}};return t;}();
    var _ = require('underscore');

    var BASE_URL = "https://api.outbound.io/v2";
    var VERSION = '1.0.0';

    var APNS = "apns";
    var GCM = "gcm";

    var API_KEY = "";

    function headers() {
        var client = 'Javascript';
        if (typeof window === 'undefined') {
            client += '-Node';
        }
        return {
            'Content-type': 'application/json',
            'X-Outbound-Client': client + '/' + VERSION,
            'X-Outbound-Key': API_KEY
        };
    }

    function error(msg, receivedCall) {
        return {
            'receivedCall': receivedCall || false,
            'message': msg
        }
    }

    function userObject(info) {
        if (!info) {
          return;
        }
        // create a data object to store top level attributes
        // only these properties can be sent in as top level
        // everything else should be in attributes {} object
        var data = {
          first_name: info.firstName,
          last_name: info.lastName,
          email: info.email,
          phone_number: info.phoneNumber,
          group_id: info.groupId,
          group_attributes: info.groupAttributes,
          previous_id: info.previousId
        };

        // only add attributes if attributes exist
        if (info.attributes) {
          data.attributes = info.attributes;
        }

        // apns & gcm are each required as an array of strings
        if (info.apnsTokens) {
          if (typeof info.apnsTokens === 'string') {
              info.apnsTokens = [info.apnsTokens];
          }
          if (Object.prototype.toString.call(info.apnsTokens) === '[object Array]') {
              data.apns = info.apnsTokens;
          }
        }
        if (info.gcmTokens) {
          if (typeof info.gcmTokens === 'string') {
              info.gcmTokens = [info.gcmTokens];
          }
          if (Object.prototype.toString.call(info.gcmTokens) === '[object Array]') {
              data.gcm = info.gcmTokens;
          }
        }

        // in order to send less useless data
        // pick out all the undefined properties
        data = _.pick(data, function(attribute){
            return !_.isUndefined(attribute);
        });

        return data;
    }

    function post(endpoint, data, deferred) {
        if (typeof module !== 'undefined') {
            var request = require('request');
            request(
                {
                    url: BASE_URL + endpoint,
                    method: 'POST',
                    headers: headers(),
                    json: data
                },
                function (err, response, body) {
                    if (err) {
                        deferred.reject(error(err.Error, false));
                    } else if(response.statusCode >= 200 && response.statusCode < 400) {
                        deferred.resolve();
                    } else {
                        deferred.reject(error(body, true));
                    }
                }
            );
        } else {
            var request = new XMLHttpRequest();
            request.open('POST', BASE_URL + endpoint, true);
            var requestHeaders = headers();
            for (var header in requestHeaders) {
                request.setRequestHeader(header, requestHeaders[header]);
            }

            request.onload = function() {
                resp = request.responseText;
                if (request.status >= 200 && request.status < 400){
                    deferred.resolve();
                } else {
                    deferred.reject(error(resp, true));
                }
            };
            request.onerror = function() {
                deferred.reject(error(null, false));
            };
            request.send(JSON.stringify(data));
        }
    }

    function getUserIdError(userId) {
      var typeofUserId = typeof userId;
      if (typeofUserId != "number" && typeofUserId != "string") {
          return error("Invalid user ID. Expected string or number, got " + typeofUserId, false);
      }
      return null;
    }

    function getTokenError(token) {
      var typeofToken = typeof token;
      if (typeofToken != "string") {
        return error("Invalid token. Expected string, got " + typeofToken, false);
      }
      return null;
    }

    function getEventError(event) {
      var typeofEvent = typeof event;
      if (typeofEvent != "string") {
          return error("Invalid event. Expected string, got " + typeofEvent, false);
      }
      return null;
    }

    function deviceToken(platform, register, userId, token) {
        var deferred = D();

        var userIdError = getUserIdError(userId);
        var tokenError = getTokenError(token);
        if (userIdError) {
            deferred.reject(userIdError);
        } else if (tokenError) {
            deferred.reject(tokenError);
        } else {
            requestData = {"user_id": userId, "token": token}
            post('/' + platform + '/' + (register ? 'register' : 'disable'), requestData, deferred);
        }
        return deferred.promise;
    }

    function Outbound(thisApiKey) {
        API_KEY = thisApiKey;
    }

    Outbound.prototype.identify = function(userId, attributes) {
        var deferred = D();

        var userIdError = getUserIdError(userId);
        if (userIdError) {
            deferred.reject(userIdError);
        } else {
            requestData = {"user_id": userId};
            user = userObject(attributes);
            for (var attr in user) {
                requestData[attr] = user[attr];
            }
            post('/identify', requestData, deferred);
        }
        return deferred.promise;
    };

    Outbound.prototype.track = function(userId, event, properties, timestamp) {
        var deferred = D();

        var userIdError = getUserIdError(userId);
        var eventError = getEventError(event);

        if (userIdError) {
            deferred.reject(userIdError);
        } else if (eventError) {
            deferred.reject(eventError);
        } else {
            requestData = {"user_id": userId, "properties": {}, "event": event};

            if (timestamp){
              requestData.timestamp = timestamp;
            } else {
              requestData.timestamp = Math.floor(Date.now() / 1000);
            }

            if (properties && typeof properties === 'object') {
                requestData.properties = properties;
            }

            post('/track', requestData, deferred);
        }

        return deferred.promise;
    };

    Outbound.prototype.trackBatch = function(events) {
      var deferred = D();

      if (!Array.isArray(events)) {
        deferred.reject(error("Invalid events array. Expected array, got " + (typeof events), false));
      } else {
        post('/track/batch', events, deferred);
      }

      return deferred.promise;
    };

    Outbound.prototype.registerApnsToken = function(userId, token) {
        return deviceToken(APNS, true, userId, token);
    };

    Outbound.prototype.registerGcmToken = function(userId, token) {
        return deviceToken(GCM, true, userId, token);
    };

    Outbound.prototype.disableApnsToken = function(userId, token) {
        return deviceToken(APNS, false, userId, token);
    };

    Outbound.prototype.disableGcmToken = function(userId, token) {
        return deviceToken(GCM, false, userId, token);
    };

    module.exports = Outbound;
})();
<commit_msg>validate batch array, including each event in it<commit_after>;(function(exports){
    var D = function(a){function b(a){j(function(){throw a})}function c(b){return this.then(b,a)}function d(b){return this.then(a,b)}function e(b,c){return this.then(function(a){return k(b)?b.apply(null,l(a)?a:[a]):t.onlyFuncs?a:b},c||a)}function f(a){function b(){a()}return this.then(b,b),this}function g(a){return this.then(function(b){return k(a)?a.apply(null,l(b)?b.splice(0,0,void 0)&&b:[void 0,b]):t.onlyFuncs?b:a},function(b){return a(b)})}function h(c){return this.then(a,c?function(a){throw c(a),a}:b)}function i(a,b){var c=o(a);if(1===c.length&&l(c[0])){if(!c[0].length)return t.fulfilled([]);c=c[0]}var d=[],e=t(),f=c.length;if(f)for(var g=(function(a){c[a]=t.promisify(c[a]),c[a].then(function(g){a in d||(d[a]=b?c[a]:g,--f||e.resolve(d))},function(g){a in d||(b?(d[a]=c[a],--f||e.resolve(d)):e.reject(g))})}),h=0,i=f;i>h;h++)g(h);else e.resolve(d);return e.promise}var j,k=function(a){return"function"==typeof a},l=function(a){return Array.isArray?Array.isArray(a):a instanceof Array},m=function(a){return!(!a||!(typeof a).match(/function|object/))},n=function(b){return b===!1||b===a||null===b},o=function(a,b){return[].slice.call(a,b)},p="undefined",q=typeof TypeError===p?Error:TypeError;if(typeof process!==p&&process.nextTick)j=process.nextTick;else if(typeof MessageChannel!==p){var r=new MessageChannel,s=[];r.port1.onmessage=function(){s.length&&s.shift()()},j=function(a){s.push(a),r.port2.postMessage(0)}}else j=function(a){setTimeout(a,0)};var t=function(b){function i(){if(0!==s){var a,b=u,c=0,d=b.length,e=~s?0:1;for(u=[];d>c;c++)(a=b[c][e])&&a(p)}}function l(a){function b(a){return function(b){return c?void 0:(c=!0,a(b))}}var c=!1;if(s)return this;try{var d=m(a)&&a.then;if(k(d)){if(a===v)throw new q("Promise can't resolve itself");return d.call(a,b(l),b(o)),this}}catch(e){return b(o)(e),this}return r(function(){p=a,s=1,i()}),this}function o(a){return s||r(function(){try{throw a}catch(b){p=b}s=-1,i()}),this}var p,r=(a!==b?b:t.alwaysAsync)?j:function(a){a()},s=0,u=[],v={then:function(a,b){var c=t();return u.push([function(b){try{n(a)?c.resolve(b):c.resolve(k(a)?a(b):t.onlyFuncs?b:a)}catch(d){c.reject(d)}},function(a){if((n(b)||!k(b)&&t.onlyFuncs)&&c.reject(a),b)try{c.resolve(k(b)?b(a):b)}catch(d){c.reject(d)}}]),0!==s&&r(i),c.promise},success:c,error:d,otherwise:d,apply:e,spread:e,ensure:f,nodify:g,rethrow:h,isPending:function(){return!(0!==s)},getStatus:function(){return s}};return v.toSource=v.toString=v.valueOf=function(){return p===a?this:p},{promise:v,resolve:l,fulfill:l,reject:o}};t.deferred=t.defer=t,t.nextTick=j,t.alwaysAsync=!0,t.onlyFuncs=!0,t.resolved=t.fulfilled=function(a){return t(!0).resolve(a).promise},t.rejected=function(a){return t(!0).reject(a).promise},t.wait=function(a){var b=t();return setTimeout(b.resolve,a||0),b.promise},t.delay=function(a,b){var c=t();return setTimeout(function(){try{c.resolve(a.apply(null))}catch(b){c.reject(b)}},b||0),c.promise},t.promisify=function(a){return a&&k(a.then)?a:t.resolved(a)},t.all=function(){return i(arguments,!1)},t.resolveAll=function(){return i(arguments,!0)},t.nodeCapsule=function(a,b){return b||(b=a,a=void 0),function(){var c=t(),d=o(arguments);d.push(function(a,b){a?c.reject(a):c.resolve(arguments.length>2?o(arguments,1):b)});try{b.apply(a,d)}catch(e){c.reject(e)}return c.promise}};return t;}();
    var _ = require('underscore');

    var BASE_URL = "https://api.outbound.io/v2";
    var VERSION = '1.0.0';

    var APNS = "apns";
    var GCM = "gcm";

    var API_KEY = "";

    function headers() {
        var client = 'Javascript';
        if (typeof window === 'undefined') {
            client += '-Node';
        }
        return {
            'Content-type': 'application/json',
            'X-Outbound-Client': client + '/' + VERSION,
            'X-Outbound-Key': API_KEY
        };
    }

    function error(msg, receivedCall) {
        return {
            'receivedCall': receivedCall || false,
            'message': msg
        }
    }

    function userObject(info) {
        if (!info) {
          return;
        }
        // create a data object to store top level attributes
        // only these properties can be sent in as top level
        // everything else should be in attributes {} object
        var data = {
          first_name: info.firstName,
          last_name: info.lastName,
          email: info.email,
          phone_number: info.phoneNumber,
          group_id: info.groupId,
          group_attributes: info.groupAttributes,
          previous_id: info.previousId
        };

        // only add attributes if attributes exist
        if (info.attributes) {
          data.attributes = info.attributes;
        }

        // apns & gcm are each required as an array of strings
        if (info.apnsTokens) {
          if (typeof info.apnsTokens === 'string') {
              info.apnsTokens = [info.apnsTokens];
          }
          if (Object.prototype.toString.call(info.apnsTokens) === '[object Array]') {
              data.apns = info.apnsTokens;
          }
        }
        if (info.gcmTokens) {
          if (typeof info.gcmTokens === 'string') {
              info.gcmTokens = [info.gcmTokens];
          }
          if (Object.prototype.toString.call(info.gcmTokens) === '[object Array]') {
              data.gcm = info.gcmTokens;
          }
        }

        // in order to send less useless data
        // pick out all the undefined properties
        data = _.pick(data, function(attribute){
            return !_.isUndefined(attribute);
        });

        return data;
    }

    function post(endpoint, data, deferred) {
        if (typeof module !== 'undefined') {
            var request = require('request');
            request(
                {
                    url: BASE_URL + endpoint,
                    method: 'POST',
                    headers: headers(),
                    json: data
                },
                function (err, response, body) {
                    if (err) {
                        deferred.reject(error(err.Error, false));
                    } else if(response.statusCode >= 200 && response.statusCode < 400) {
                        deferred.resolve();
                    } else {
                        deferred.reject(error(body, true));
                    }
                }
            );
        } else {
            var request = new XMLHttpRequest();
            request.open('POST', BASE_URL + endpoint, true);
            var requestHeaders = headers();
            for (var header in requestHeaders) {
                request.setRequestHeader(header, requestHeaders[header]);
            }

            request.onload = function() {
                resp = request.responseText;
                if (request.status >= 200 && request.status < 400){
                    deferred.resolve();
                } else {
                    deferred.reject(error(resp, true));
                }
            };
            request.onerror = function() {
                deferred.reject(error(null, false));
            };
            request.send(JSON.stringify(data));
        }
    }

    function getUserIdError(userId) {
      var typeofUserId = typeof userId;
      if (typeofUserId != "number" && typeofUserId != "string") {
          return error("Invalid user ID. Expected string or number, got " + typeofUserId, false);
      }
      return null;
    }

    function getTokenError(token) {
      var typeofToken = typeof token;
      if (typeofToken != "string") {
        return error("Invalid token. Expected string, got " + typeofToken, false);
      }
      return null;
    }

    function getEventError(event) {
      var typeofEvent = typeof event;
      if (typeofEvent != "string") {
          return error("Invalid event. Expected string, got " + typeofEvent, false);
      }
      return null;
    }

    function deviceToken(platform, register, userId, token) {
        var deferred = D();

        var userIdError = getUserIdError(userId);
        var tokenError = getTokenError(token);
        if (userIdError) {
            deferred.reject(userIdError);
        } else if (tokenError) {
            deferred.reject(tokenError);
        } else {
            requestData = {"user_id": userId, "token": token}
            post('/' + platform + '/' + (register ? 'register' : 'disable'), requestData, deferred);
        }
        return deferred.promise;
    }

    function Outbound(thisApiKey) {
        API_KEY = thisApiKey;
    }

    Outbound.prototype.identify = function(userId, attributes) {
        var deferred = D();

        var userIdError = getUserIdError(userId);
        if (userIdError) {
            deferred.reject(userIdError);
        } else {
            requestData = {"user_id": userId};
            user = userObject(attributes);
            for (var attr in user) {
                requestData[attr] = user[attr];
            }
            post('/identify', requestData, deferred);
        }
        return deferred.promise;
    };

    Outbound.prototype.track = function(userId, event, properties, timestamp) {
        var deferred = D();

        var userIdError = getUserIdError(userId);
        var eventError = getEventError(event);

        if (userIdError) {
            deferred.reject(userIdError);
        } else if (eventError) {
            deferred.reject(eventError);
        } else {
            requestData = {"user_id": userId, "properties": {}, "event": event};

            if (timestamp){
              requestData.timestamp = timestamp;
            } else {
              requestData.timestamp = Math.floor(Date.now() / 1000);
            }

            if (properties && typeof properties === 'object') {
                requestData.properties = properties;
            }

            post('/track', requestData, deferred);
        }

        return deferred.promise;
    };

    Outbound.prototype.trackBatch = function(events) {
      var deferred = D();
      var userIdError;
      var eventError;

      if (!Array.isArray(events)) {
        deferred.reject(error("Invalid events array. Expected array, got " + (typeof events), false));
      } else {
        if (events.length > 100) {
          deferred.reject(error("Events array can not contain more than 100 events. Got " + events.length, false));
        } else {
          for (var i = 0, len = events.length; i < len; i++) {
            // validate user_id and event in each event
            userIdError = getUserIdError(events[i].user_id);
            if (userIdError) {
              deferred.reject(userIdError);
              return deferred.promise;
            } else {
              eventError = getEventError(events[i].event);
              if (eventError) {
                deferred.reject(eventError);
                return deferred.promise;
              }
            }
          }

          post('/track/batch', events, deferred);
        }
      }

      return deferred.promise;
    };

    Outbound.prototype.registerApnsToken = function(userId, token) {
        return deviceToken(APNS, true, userId, token);
    };

    Outbound.prototype.registerGcmToken = function(userId, token) {
        return deviceToken(GCM, true, userId, token);
    };

    Outbound.prototype.disableApnsToken = function(userId, token) {
        return deviceToken(APNS, false, userId, token);
    };

    Outbound.prototype.disableGcmToken = function(userId, token) {
        return deviceToken(GCM, false, userId, token);
    };

    module.exports = Outbound;
})();
<|endoftext|>


<commit_before>var silab = silab || {};

String.prototype.capitalize = function () {
    return this.charAt(0).toUpperCase() + this.slice(1);
}
String.prototype.deentitize = function () {
    var ret = this.replace(/>/g, '>');
    ret = ret.replace(/</g, '<');
    ret = ret.replace(/"/g, '"');
    ret = ret.replace(/'/g, "'");
    ret = ret.replace(/&/g, '&');
    return ret;
},

silab.tags = [];
silab.colors = [
    "aqua",
    "red",
    "green",
    "orange",
    "yellow",
    "white",
    "teal",
    "maroon",
];

silab.itemsIcons = {
    reactive    :   "fa fa-hourglass-end",
    materials   :   "fa fa-eyedropper",
    teams       :   "fa fa-laptop",
    tools       :   "fa fa-gavel",
    accesories  :   "fa fa-laptop",
}

silab.itemsIcons.reactivo       = silab.itemsIcons.reactive;
silab.itemsIcons.material       = silab.itemsIcons.materials;
silab.itemsIcons.equipo         = silab.itemsIcons.teams;
silab.itemsIcons.herramienta    = silab.itemsIcons.tools;
silab.itemsIcons.accesorio      = silab.itemsIcons.accesories;

silab.consts = {
    MAX_NOT_CONSUMIBLE : 1
}

silab.needs = function(needs, moduleName)
{
    let isValid = true;
    moduleName  = moduleName || "Silab";

    // Module needs
    if(__needs())
    {
        var needs = needs || [ ];
        for(var need in needs)
        {
            if( !silab.checkProperty( needs [ need ], window ) )
            {
                throw  moduleName + ".js, necesita de '" + needs [ need ] + "'";
            }
        }
    }

    // core needs dependencies
    function __needs()
    {
        let needs   = [ "jQuery", { key: "underscore", value : "_" } ];
        let isValid = true;

        for(var need in needs)
        {
            var isObject = Object.prototype.toString.call( needs [ need ] ) === '[object Object]';

            if( !silab.checkProperty( ((isObject) ? needs [ need ][ "value" ] : needs [ need ]), window ) )
            {
                throw "silab.js, necesita basicamente de '" + ((isObject) ? needs [ need ][ "key" ] : needs [ need ] ) + "'";
            }

        }

        return isValid;
    }

    // splits by dot

    return isValid;
}

silab.basics = function() {

    if(typeof $ !== "undefined") {
        $(document).on('ready', silab_init);
    }

    function silab_init() {

        console.log( "app!" );
        clickableAlertsDimissible();
        activeTab();
        bindLinkWithHash();
        getLaboratories();
        accordionToggle();
        collapsableField();
    }

    function bindLinkWithHash()
    {
        $("a[href*='#']").on('click', function (){
            // 1. Obtenenmos el "href" del link
            let href = $(this).attr("href");
            // 2. Obtenemos su hash
            let hash = href.substr(href.indexOf("#"));

            if(hash.length > 1)
                activeTab(hash);
        });
    }

    function activeTab(hash) {

        var hash = hash || window.location.hash;
        console.log("hash:", hash);
        if(typeof hash !== "undefined")
        {
            let anchor = $('a[role="tab"][href="' + hash + '"]');
            if(typeof anchor !== "undefined")
            {
                anchor.tab('show');
                anchor.parents("li").addClass("active");
            }

        }
    }

    function getLaboratories(size)
    {
        var domain  = $("body").data("domain");
        size        = size || 5;

        $.ajax({
            url     :   domain + "/laboratorio/get-all?page=" + size,
            type    :   "GET",
            success :   renderLaboratories
        });

        function renderLaboratories(data)
        {
            let targetMenu  = "#laboratories-menu";
                targetMenu  += " ul.treeview-menu";
            var ref         = $(targetMenu);

            var items       = "
<a href='" + domain + "/laboratorio/manager/<%= LABO_ID %>'><i class='fa fa-circle-o text-<%= color %>'><%= LABO_NOMBRE %>
";
            var template    = _.template(items);

            _.each(data, function(laboratory){
                let silabCount      = silab.colors.length;
                laboratory.color    = silab.colors[ _.random(0, silabCount - 1) ];
                ref.append( template( laboratory ) );
            });

            console.log(data);
        }
    }

    function clickableAlertsDimissible()
    {
        $("body").on("click", ".alert.alert-dismissible", hideAnimated);

        function hideAnimated(e)
        {
            let me = $(this);

            me.fadeOut("slow");
        }
    }

    function ajaxConfiguration()
    {
        $( document ).ajaxStart(function() {
            $( "#loading" ).show();
        });
    }

    function accordionToggle()
    {
        if( silab.needs() ) {
            $('body').on('click', '[data-toggle=\'collapse\'][data-target]', accordionHandler);

            function accordionHandler(e)
            {
                let me       = $(this);
                let next     = $(me.data( 'next' ));
                let target   = $(me.data( 'target' ));
                let nextCopy    = me.data( 'next' );
                let targetCopy  = me.data( 'target' );

                next.collapse('show');
                target.collapse('hide');

                me.data( 'next', targetCopy );
                me.data( 'target', nextCopy );

            }
        }
    }

    function collapsableField() {
        if( silab.needs() ) {
            $("body").on( "click", '[data-collapsable-trigger]', collapseFieldHandler);

            function collapseFieldHandler(e){
                let me       = $(this);
                let myData   = me.data();

                let _default  = $(myData[ "defaultTarget" ] );
                let formField = $( myData[ "formField" ] );

                if( me.prop("checked") ) {
                    _default.val( _default.data( "defaultOff" ) );
                    formField.attr( "required", true );
                }
                else {
                    _default.val( _default.data( "defaultValue" ) );
                    formField.removeAttr( "required" );
                }

                $(myData[ "href" ]).collapse( me.prop("checked") ? "show" : "hide" );
            }
        }
    }
}

silab.registerTabIds = function(tabs) {

    if( Object.prototype.toString.call( tabs ) === '[object Array]' ) {

    }
}

silab.basics();

/**
 * @author Jeancarlo Fontalvo
 * @param property la propiedad a checkear si se encuentra en el objecto
 * @param object Objecto target
 * @return boleano falso si no se encuentra la propiedad o verdadero si se encuentra
 */
silab.checkProperty = function(property, object)
{
    if(property !== null || typeof property !== "undefined")
    {
        var dotted = property.split(".");
        if(dotted.length > 0)
        {
            var current = null;
            for(var i = 0; i < dotted.length; i++)
            {
                if(current == null)
                    current = object[ dotted[ i ] ];
                else
                    current = current[ dotted[ i ] ];

                if(typeof current === "undefined")
                    return false;
            }

            return true;
        }

    }

    return false;
}

silab.helpers = {
    getTemplate : function(params)
    {
        if(silab.needs())
        {
            if(!_.isUndefined(params))
            {
                let targets = { source: "#templates", target: "" };

                if (!_.isUndefined(params.source))
                    targets.source = params.source;

                if (!_.isUndefined(params.target))
                    targets.target = params.target;

                let isGrouped = !_.isUndefined(params.isGrouped) ? params.isGrouped : false;

                let html = $(targets.source).html();

                if (isGrouped) {
                    var template = $(targets.target, html);
                    html         = template.html().deentitize();
                }

                return html;
            }
        }

        return "";
    },
    pushNotification: function(params, callback)
    {
        if( silab.needs() ) {
            $.post("/notify/" + params.type, params.data, callback);
        }
    },
    appendOption: function(data)
    {
        if( silab.needs() ) {
            if( !_.isUndefined(data) ) {
                var option      = new Option(data.text, data.value);

                option.selected = !_.isUndefined(data.selected) ? data.selected : false;

                for(var key in data.data) {
                    option.setAttribute("data-" + key, data.data[ key ]);
                }

                data.select.append( option );
                data.select.trigger("change");
            }

        }
    },
    addAlert: function(target, data, autoHide)
    {
        if( silab.needs() )
        {
            var isSuccess   = data.status == 0;
            var autoHide    = !_.isUndefined( autoHide ) ? autoHide : false;

            var alertHtml   = silab.helpers.getTemplate({
                                    target: '#alert-dimissible',
                                    isGrouped: true
                                });

            var template = _.template( alertHtml );
            var message  = data.message;
            var result   = template({
                                type:  isSuccess ? 'success' : 'danger',
                                icon: {
                                    class: 'icon icon-bottom material-icons',
                                    text: (isSuccess ? 'check_circle': 'error')
                                },
                                title: isSuccess ? 'Enhorabuena' : 'Opps!',
                                content: message
                            });

            $(target).html( result );
            // - - - Auto hide the alert :v
            if(autoHide) {
                $(target + ' .alert').fadeTo(2000, 500).delay(5000).slideUp(500);
            }
        }
    },
    grid: {
        getSelectedRows: function ( grid ) {
            if( silab.needs(["jQuery.fn.yiiGridView", "Storages.sessionStorage"]) ) {

                var $grid       = $(grid);
                var sStorage    = Storages.sessionStorage;
                var data        = $grid.yiiGridView('data');
                var keys        = [];

                if (data.selectionColumn) {
                    $grid.find("input[name='" + data.selectionColumn + "']:checked").each(function () {
                        let record = $(this).parent().closest('tr');
                        let data   = record.data();

                        let item   = {
                            id : data.key,
                            info : data.item
                        };
                        keys.push( item );
                        console.log( item )
                    });
                }

                if( sStorage.isSet("stocks.selected") ) {
                    keys = _.uniq(_.union(keys, sStorage.get("stocks.selected")), false, _.property( 'id' ) );
                }

                if( keys.length ) {
                    sStorage.set("stocks.selected", keys );
                }
                return keys;
            }

            return [];
        },
        selectRows: function( grid, keys ) {
            if( silab.needs(["jQuery.fn.yiiGridView", "Storages.sessionStorage"]) ) {

                var $grid       = $(grid);
                var sStorage    = Storages.sessionStorage;
                var data        = $grid.yiiGridView('data');

                if(sStorage.isSet("stocks.selected")) {
                    keys = sStorage.get("stocks.selected");
                }

                if ( data.selectionColumn ) {
                    _.each(keys, function(i){
                        let check = $grid.find( "[data-key='" + i.id + "']" ).find("input[name='" + data.selectionColumn + "']");
                            check.prop("checked", true);
                    });
                }

                return keys;
            }
        }
    }
};

silab.ajax = function(options)
{
    var trigger = options.trigger;

    function beforeAjax()
    {
        silab.overlay.toggle( "process", "Procesando..." );
    }

    function completeAjax()
    {
        silab.overlay.toggle( "process", "Procesando..." );
    }

    options.beforeSend = options.beforeSend || beforeAjax;
    options.complete   = options.complete   || completeAjax;

    $.ajax(options);

}

silab.ajaxStart = function(handler)
{
    handler();
}

silab.submitForm = function(form, data)
{
    var me          = getForm(form);
    var dataToSend  = data;

    function getForm(form)
    {
        if(Object.prototype.toString.call( form ) === '[object String]')
            return $(form);

        return form;
    }

    me.on('beforeSubmit', { "form": me, "dataToSend": dataToSend } ,function(e){
        // - - - - Stop propagation
            e.preventDefault();
            e.stopPropagation();
        // - - - - It's Maui Time!
        let form = $(this);

        silab.ajax(
            {
                url: form.attr('action'),
                data:  e.data.dataToSend || form.serialize(),
                success: success,
                type: "POST",
                trigger: form.find("button[type='submit']")
            }
        );

        function success(data)
        {
            var insideModal = $('form[id*=\'item\']').animate({ scrollTop: 0 }, 'slow');

            displayAlert(data);

            reset(e.data.form);
        }

        function displayAlert(data)
        {
            let parent      = $('form[id*=\'item\']').closest('.modal');
                parent      = parent.length ? parent : $('html, body');

            data.message    = _.template( data.message )( { } );

            parent.animate({ scrollTop: 0 }, 'slow');

            silab.helpers.addAlert('#item-alert-spot', data, true);

            if( typeof window.itemFormCallback !== 'undefined' )
            {
                window.itemFormCallback( data );
            }

        }

        return false;
    });
    // reseter trigger
    me.find("[data-form-reseter]").on('click', { "form" : me }, function(e){
        let form    = e.data.form;
        // reset the form
        reset(form);
    });

    function reset(form)
    {
        form[ 0 ].reset();
        form.find('select').val('').trigger('change');
    }
}

silab.overlay = {
    toggle: function (mode, message)
    {
        if(silab.needs()) {

            let overlay     = $("#overlay-block");
            let target      = null;
            let messageSpot = overlay.find("p");

            // Check the spinner mode
            switch( mode ) {
                case 'load':
                    target = overlay.find("[data-load]");
                break;

                case 'process':
                    target = overlay.find("[data-process]");
                break;
            }

            // Si hay un spinner entonces muestrelo u ocultelo
            if(target != null)
            {
                target .toggleClass("hide")
            }

            overlay.toggleClass("hide");
            messageSpot.text( message || "" );
        }

    }
}<commit_msg>:coffee: Iconos de items en Silab.app.js<commit_after>var silab = silab || {};

String.prototype.capitalize = function () {
    return this.charAt(0).toUpperCase() + this.slice(1);
}
String.prototype.deentitize = function () {
    var ret = this.replace(/>/g, '>');
    ret = ret.replace(/</g, '<');
    ret = ret.replace(/"/g, '"');
    ret = ret.replace(/'/g, "'");
    ret = ret.replace(/&/g, '&');
    return ret;
},

silab.tags = [];
silab.colors = [
    "aqua",
    "red",
    "green",
    "orange",
    "yellow",
    "white",
    "teal",
    "maroon",
];

silab.itemsTypes = {
     consumible    : {
         text : "Consumible",
         value: 1,
         icon : "fa fa-hourglass-end"
     },
     noconsumible  : {
         text : "No Consumible",
         value: 2,
         icon : "fa fa-hourglass-end"
     },
     reactivo      : {
         text : "Reactivo",
         value: 3,
         icon : "fa fa-hourglass-end"
     },
     material      : {
         text : "Material",
         value: 4,
         icon : "fa fa-eyedropper"
     },
     equipo        : {
         text : "Equipo",
         value: 5,
         icon : "fa fa fa-laptop"
     },
     accesorio     : {
         text : "Accesorio",
         value: 6,
         icon : "fa fa-laptop"
     },
     herramienta   : {
         text : "Herramienta",
         value: 7,
         icon : "fa fa-gavel"
     }
}

silab.consts = {
    MAX_NOT_CONSUMIBLE : 1
}

silab.needs = function(needs, moduleName)
{
    let isValid = true;
    moduleName  = moduleName || "Silab";

    // Module needs
    if(__needs())
    {
        var needs = needs || [ ];
        for(var need in needs)
        {
            if( !silab.checkProperty( needs [ need ], window ) )
            {
                throw  moduleName + ".js, necesita de '" + needs [ need ] + "'";
            }
        }
    }

    // core needs dependencies
    function __needs()
    {
        let needs   = [ "jQuery", { key: "underscore", value : "_" } ];
        let isValid = true;

        for(var need in needs)
        {
            var isObject = Object.prototype.toString.call( needs [ need ] ) === '[object Object]';

            if( !silab.checkProperty( ((isObject) ? needs [ need ][ "value" ] : needs [ need ]), window ) )
            {
                throw "silab.js, necesita basicamente de '" + ((isObject) ? needs [ need ][ "key" ] : needs [ need ] ) + "'";
            }

        }

        return isValid;
    }

    // splits by dot

    return isValid;
}

silab.basics = function() {

    if(typeof $ !== "undefined") {
        $(document).on('ready', silab_init);
    }

    function silab_init() {

        console.log( "app!" );
        clickableAlertsDimissible();
        activeTab();
        bindLinkWithHash();
        getLaboratories();
        accordionToggle();
        collapsableField();
    }

    function bindLinkWithHash()
    {
        $("a[href*='#']").on('click', function (){
            // 1. Obtenenmos el "href" del link
            let href = $(this).attr("href");
            // 2. Obtenemos su hash
            let hash = href.substr(href.indexOf("#"));

            if(hash.length > 1)
                activeTab(hash);
        });
    }

    function activeTab(hash) {

        var hash = hash || window.location.hash;
        console.log("hash:", hash);
        if(typeof hash !== "undefined")
        {
            let anchor = $('a[role="tab"][href="' + hash + '"]');
            if(typeof anchor !== "undefined")
            {
                anchor.tab('show');
                anchor.parents("li").addClass("active");
            }

        }
    }

    function getLaboratories(size)
    {
        var domain  = $("body").data("domain");
        size        = size || 5;

        $.ajax({
            url     :   domain + "/laboratorio/get-all?page=" + size,
            type    :   "GET",
            success :   renderLaboratories
        });

        function renderLaboratories(data)
        {
            let targetMenu  = "#laboratories-menu";
                targetMenu  += " ul.treeview-menu";
            var ref         = $(targetMenu);

            var items       = "
<a href='" + domain + "/laboratorio/manager/<%= LABO_ID %>'><i class='fa fa-circle-o text-<%= color %>'><%= LABO_NOMBRE %>
";
            var template    = _.template(items);

            _.each(data, function(laboratory){
                let silabCount      = silab.colors.length;
                laboratory.color    = silab.colors[ _.random(0, silabCount - 1) ];
                ref.append( template( laboratory ) );
            });

            console.log(data);
        }
    }

    function clickableAlertsDimissible()
    {
        $("body").on("click", ".alert.alert-dismissible", hideAnimated);

        function hideAnimated(e)
        {
            let me = $(this);

            me.fadeOut("slow");
        }
    }

    function ajaxConfiguration()
    {
        $( document ).ajaxStart(function() {
            $( "#loading" ).show();
        });
    }

    function accordionToggle()
    {
        if( silab.needs() ) {
            $('body').on('click', '[data-toggle=\'collapse\'][data-target]', accordionHandler);

            function accordionHandler(e)
            {
                let me       = $(this);
                let next     = $(me.data( 'next' ));
                let target   = $(me.data( 'target' ));
                let nextCopy    = me.data( 'next' );
                let targetCopy  = me.data( 'target' );

                next.collapse('show');
                target.collapse('hide');

                me.data( 'next', targetCopy );
                me.data( 'target', nextCopy );

            }
        }
    }

    function collapsableField() {
        if( silab.needs() ) {
            $("body").on( "click", '[data-collapsable-trigger]', collapseFieldHandler);

            function collapseFieldHandler(e){
                let me       = $(this);
                let myData   = me.data();

                let _default  = $(myData[ "defaultTarget" ] );
                let formField = $( myData[ "formField" ] );

                if( me.prop("checked") ) {
                    _default.val( _default.data( "defaultOff" ) );
                    formField.attr( "required", true );
                }
                else {
                    _default.val( _default.data( "defaultValue" ) );
                    formField.removeAttr( "required" );
                }

                $(myData[ "href" ]).collapse( me.prop("checked") ? "show" : "hide" );
            }
        }
    }
}

silab.registerTabIds = function(tabs) {

    if( Object.prototype.toString.call( tabs ) === '[object Array]' ) {

    }
}

silab.basics();

/**
 * @author Jeancarlo Fontalvo
 * @param property la propiedad a checkear si se encuentra en el objecto
 * @param object Objecto target
 * @return boleano falso si no se encuentra la propiedad o verdadero si se encuentra
 */
silab.checkProperty = function(property, object)
{
    if(property !== null || typeof property !== "undefined")
    {
        var dotted = property.split(".");
        if(dotted.length > 0)
        {
            var current = null;
            for(var i = 0; i < dotted.length; i++)
            {
                if(current == null)
                    current = object[ dotted[ i ] ];
                else
                    current = current[ dotted[ i ] ];

                if(typeof current === "undefined")
                    return false;
            }

            return true;
        }

    }

    return false;
}

silab.helpers = {
    getTemplate : function(params)
    {
        if(silab.needs())
        {
            if(!_.isUndefined(params))
            {
                let targets = { source: "#templates", target: "" };

                if (!_.isUndefined(params.source))
                    targets.source = params.source;

                if (!_.isUndefined(params.target))
                    targets.target = params.target;

                let isGrouped = !_.isUndefined(params.isGrouped) ? params.isGrouped : false;

                let html = $(targets.source).html();

                if (isGrouped) {
                    var template = $(targets.target, html);
                    html         = template.html().deentitize();
                }

                return html;
            }
        }

        return "";
    },
    pushNotification: function(params, callback)
    {
        if( silab.needs() ) {
            $.post("/notify/" + params.type, params.data, callback);
        }
    },
    appendOption: function(data)
    {
        if( silab.needs() ) {
            if( !_.isUndefined(data) ) {
                var option      = new Option(data.text, data.value);

                option.selected = !_.isUndefined(data.selected) ? data.selected : false;

                for(var key in data.data) {
                    option.setAttribute("data-" + key, data.data[ key ]);
                }

                data.select.append( option );
                data.select.trigger("change");
            }

        }
    },
    addAlert: function(target, data, autoHide)
    {
        if( silab.needs() )
        {
            var isSuccess   = data.status == 0;
            var autoHide    = !_.isUndefined( autoHide ) ? autoHide : false;

            var alertHtml   = silab.helpers.getTemplate({
                                    target: '#alert-dimissible',
                                    isGrouped: true
                                });

            var template = _.template( alertHtml );
            var message  = data.message;
            var result   = template({
                                type:  isSuccess ? 'success' : 'danger',
                                icon: {
                                    class: 'icon icon-bottom material-icons',
                                    text: (isSuccess ? 'check_circle': 'error')
                                },
                                title: isSuccess ? 'Enhorabuena' : 'Opps!',
                                content: message
                            });

            $(target).html( result );
            // - - - Auto hide the alert :v
            if(autoHide) {
                $(target + ' .alert').fadeTo(2000, 500).delay(5000).slideUp(500);
            }
        }
    },
    grid: {
        getSelectedRows: function ( grid ) {
            if( silab.needs(["jQuery.fn.yiiGridView", "Storages.sessionStorage"]) ) {

                var $grid       = $(grid);
                var sStorage    = Storages.sessionStorage;
                var data        = $grid.yiiGridView('data');
                var keys        = [];

                if (data.selectionColumn) {
                    $grid.find("input[name='" + data.selectionColumn + "']:checked").each(function () {
                        let record = $(this).parent().closest('tr');
                        let data   = record.data();

                        let item   = {
                            id : data.key,
                            info : data.item
                        };
                        keys.push( item );
                        console.log( item )
                    });
                }

                if( sStorage.isSet("stocks.selected") ) {
                    keys = _.uniq(_.union(keys, sStorage.get("stocks.selected")), false, _.property( 'id' ) );
                }

                if( keys.length ) {
                    sStorage.set("stocks.selected", keys );
                }
                return keys;
            }

            return [];
        },
        selectRows: function( grid, keys ) {
            if( silab.needs(["jQuery.fn.yiiGridView", "Storages.sessionStorage"]) ) {

                var $grid       = $(grid);
                var sStorage    = Storages.sessionStorage;
                var data        = $grid.yiiGridView('data');

                if(sStorage.isSet("stocks.selected")) {
                    keys = sStorage.get("stocks.selected");
                }

                if ( data.selectionColumn ) {
                    _.each(keys, function(i){
                        let check = $grid.find( "[data-key='" + i.id + "']" ).find("input[name='" + data.selectionColumn + "']");
                            check.prop("checked", true);
                    });
                }

                return keys;
            }
        }
    }
};

silab.ajax = function(options)
{
    var trigger = options.trigger;

    function beforeAjax()
    {
        silab.overlay.toggle( "process", "Procesando..." );
    }

    function completeAjax()
    {
        silab.overlay.toggle( "process", "Procesando..." );
    }

    options.beforeSend = options.beforeSend || beforeAjax;
    options.complete   = options.complete   || completeAjax;

    $.ajax(options);

}

silab.ajaxStart = function(handler)
{
    handler();
}

silab.submitForm = function(form, data, config)
{
    var me          = getForm(form);
    var dataToSend  = data;
    var config      = config || {
        "alert-spot" : ".alert-spot"
    };

    function getForm(form)
    {
        if(Object.prototype.toString.call( form ) === '[object String]')
            return $(form);

        return form;
    }

    me.on('beforeSubmit', { "form": me, "dataToSend": dataToSend } ,function(e){
        // - - - - Stop propagation
            e.preventDefault();
            e.stopPropagation();
        // - - - - It's Maui Time!
        let form = $(this);

        silab.ajax(
            {
                url: form.attr('action'),
                data:  e.data.dataToSend || form.serialize(),
                success: success,
                type: "POST",
                trigger: form.find("button[type='submit']")
            }
        );

        function success(data)
        {
            var insideModal = $('form[id*=\'item\']').animate({ scrollTop: 0 }, 'slow');

            displayAlert(data);

            // - - - Executar la accion de refrescado o redireccion - - -
            if( !_.isUndefined( data.action ) ) {
                setTimeout(function() {
                    window.location[ data.action.type ]( data.action.value );
                }, 2000);
            }

            reset(e.data.form);
        }

        function displayAlert(data)
        {
            let parent      = $('form[id*=\'item\']').closest('.modal');
                parent      = parent.length ? parent : $('html, body');

            data.message    = _.template( data.message )( { } );

            parent.animate({ scrollTop: 0 }, 'slow');

            silab.helpers.addAlert( config[ "alert-spot" ], data, true);

            if( typeof window.itemFormCallback !== 'undefined' )
            {
                window.itemFormCallback( data );
            }

        }

        return false;
    });
    // reseter trigger
    me.find("[data-form-reseter]").on('click', { "form" : me }, function(e){
        let form    = e.data.form;
        // reset the form
        reset(form);
    });

    function reset(form)
    {
        form[ 0 ].reset();
        form.find('select').val('').trigger('change');
    }
}

silab.overlay = {
    toggle: function (mode, message)
    {
        if(silab.needs()) {

            let overlay     = $("#overlay-block");
            let target      = null;
            let messageSpot = overlay.find("p");

            // Check the spinner mode
            switch( mode ) {
                case 'load':
                    target = overlay.find("[data-load]");
                break;

                case 'process':
                    target = overlay.find("[data-process]");
                break;
            }

            // Si hay un spinner entonces muestrelo u ocultelo
            if(target != null)
            {
                target .toggleClass("hide")
            }

            overlay.toggleClass("hide");
            messageSpot.text( message || "" );
        }

    }
}<|endoftext|>


<commit_before>var Parser = require('jsonparse')
  , Stream = require('stream').Stream
  , through = require('through')

/*

  the value of this.stack that creationix's jsonparse has is weird.

  it makes this code ugly, but his problem is way harder that mine,
  so i'll forgive him.

*/

exports.parse = function (path) {

  var parser = new Parser()
  var stream = through(function (chunk) {
    if('string' === typeof chunk) {
      if (process.browser) {
        var buf = new Array(chunk.length)
        for (var i = 0; i < chunk.length; i++) buf[i] = chunk.charCodeAt(i)
        chunk = new Int32Array(buf)
      } else {
        chunk = new Buffer(chunk)
      }
    }
    parser.write(chunk)
  },
  function (data) {
    if(data)
      stream.write(data)
    stream.queue(null)
  })

  if('string' === typeof path)
    path = path.split('.').map(function (e) {
      if (e === '*')
        return true
      else if (e === '') // '..'.split('.') returns an empty string
        return {recurse: true}
      else
        return e
    })

  var count = 0, _key
  if(!path || !path.length)
    path = null

  parser.onValue = function () {
    if (!this.root && this.stack.length == 1)
      stream.root = this.value

    if(! path) return

    var i = 0 // iterates on path
    var j  = 0 // iterates on stack
    while (i < path.length) {
      var key = path[i]
      var c
      j++

      if (key && !key.recurse) {
        c = (j === this.stack.length) ? this : this.stack[j]
        if (!c) return
        if (! check(key, c.key)) return
        i++
      } else {
        i++
        var nextKey = path[i]
        if (! nextKey) return
        while (true) {
          c = (j === this.stack.length) ? this : this.stack[j]
          if (!c) return
          if (check(nextKey, c.key)) { i++; break}
          j++
        }
      }
    }
    if (j !== this.stack.length) return

    count ++
    if(null != this.value[this.key])
      stream.queue(this.value[this.key])
    delete this.value[this.key]
  }
  parser._onToken = parser.onToken;

  parser.onToken = function (token, value) {
    parser._onToken(token, value);
    if (this.stack.length === 0) {
      if (stream.root) {
        if(!path)
          stream.queue(stream.root)
        stream.emit('root', stream.root, count)
        count = 0;
        stream.root = null;
      }
    }
  }

  parser.onError = function (err) {
    stream.emit('error', err)
  }

  return stream
}

function check (x, y) {
  if ('string' === typeof x)
    return y == x
  else if (x && 'function' === typeof x.exec)
    return x.exec(y)
  else if ('boolean' === typeof x)
    return x
  else if ('function' === typeof x)
    return x(y)
  return false
}

exports.stringify = function (op, sep, cl) {
  if (op === false){
    op = ''
    sep = '\n'
    cl = ''
  } else if (op == null) {

    op = '[\n'
    sep = '\n,\n'
    cl = '\n]\n'

  }

  //else, what ever you like

  var stream
    , first = true
    , anyData = false
  stream = through(function (data) {
    anyData = true
    var json = JSON.stringify(data)
    if(first) { first = false ; stream.queue(op + json)}
    else stream.queue(sep + json)
  },
  function (data) {
    if(!anyData)
      stream.queue(op)
    stream.queue(cl)
    stream.queue(null)
  })

  return stream
}

exports.stringifyObject = function (op, sep, cl) {
  if (op === false){
    op = ''
    sep = '\n'
    cl = ''
  } else if (op == null) {

    op = '{\n'
    sep = '\n,\n'
    cl = '\n}\n'

  }

  //else, what ever you like

  var stream = new Stream ()
    , first = true
    , anyData = false
  stream = through(function (data) {
    anyData = true
    var json = JSON.stringify(data[0]) + ':' + JSON.stringify(data[1])
    if(first) { first = false ; stream.queue(op + json)}
    else stream.queue(sep + json)
  },
  function (data) {
    if(!anyData) stream.queue(op)
    stream.queue(cl)

    stream.queue(null)
  })

  return stream
}
<commit_msg>work as cli tool, plus mapper function<commit_after>#! /usr/bin/env node

var Parser = require('jsonparse')
  , Stream = require('stream').Stream
  , through = require('through')

/*

  the value of this.stack that creationix's jsonparse has is weird.

  it makes this code ugly, but his problem is way harder that mine,
  so i'll forgive him.

*/

exports.parse = function (path, map) {

  var parser = new Parser()
  var stream = through(function (chunk) {
    if('string' === typeof chunk) {
      if (process.browser) {
        var buf = new Array(chunk.length)
        for (var i = 0; i < chunk.length; i++) buf[i] = chunk.charCodeAt(i)
        chunk = new Int32Array(buf)
      } else {
        chunk = new Buffer(chunk)
      }
    }
    parser.write(chunk)
  },
  function (data) {
    if(data)
      stream.write(data)
    stream.queue(null)
  })

  if('string' === typeof path)
    path = path.split('.').map(function (e) {
      if (e === '*')
        return true
      else if (e === '') // '..'.split('.') returns an empty string
        return {recurse: true}
      else
        return e
    })

  var count = 0, _key
  if(!path || !path.length)
    path = null

  parser.onValue = function () {
    if (!this.root && this.stack.length == 1)
      stream.root = this.value

    if(! path) return

    var i = 0 // iterates on path
    var j  = 0 // iterates on stack
    while (i < path.length) {
      var key = path[i]
      var c
      j++

      if (key && !key.recurse) {
        c = (j === this.stack.length) ? this : this.stack[j]
        if (!c) return
        if (! check(key, c.key)) return
        i++
      } else {
        i++
        var nextKey = path[i]
        if (! nextKey) return
        while (true) {
          c = (j === this.stack.length) ? this : this.stack[j]
          if (!c) return
          if (check(nextKey, c.key)) { i++; break}
          j++
        }
      }
    }
    if (j !== this.stack.length) return

    count ++
    var data = this.value[this.key]
    if(null != data)
      stream.queue(map ? map(data) : data)
    delete this.value[this.key]
  }
  parser._onToken = parser.onToken;

  parser.onToken = function (token, value) {
    parser._onToken(token, value);
    if (this.stack.length === 0) {
      if (stream.root) {
        if(!path)
          stream.queue(stream.root)
        stream.emit('root', stream.root, count)
        count = 0;
        stream.root = null;
      }
    }
  }

  parser.onError = function (err) {
    stream.emit('error', err)
  }

  return stream
}

function check (x, y) {
  if ('string' === typeof x)
    return y == x
  else if (x && 'function' === typeof x.exec)
    return x.exec(y)
  else if ('boolean' === typeof x)
    return x
  else if ('function' === typeof x)
    return x(y)
  return false
}

exports.stringify = function (op, sep, cl) {
  if (op === false){
    op = ''
    sep = '\n'
    cl = ''
  } else if (op == null) {

    op = '[\n'
    sep = '\n,\n'
    cl = '\n]\n'

  }

  //else, what ever you like

  var stream
    , first = true
    , anyData = false
  stream = through(function (data) {
    anyData = true
    var json = JSON.stringify(data)
    if(first) { first = false ; stream.queue(op + json)}
    else stream.queue(sep + json)
  },
  function (data) {
    if(!anyData)
      stream.queue(op)
    stream.queue(cl)
    stream.queue(null)
  })

  return stream
}

exports.stringifyObject = function (op, sep, cl) {
  if (op === false){
    op = ''
    sep = '\n'
    cl = ''
  } else if (op == null) {

    op = '{\n'
    sep = '\n,\n'
    cl = '\n}\n'

  }

  //else, what ever you like

  var stream = new Stream ()
    , first = true
    , anyData = false
  stream = through(function (data) {
    anyData = true
    var json = JSON.stringify(data[0]) + ':' + JSON.stringify(data[1])
    if(first) { first = false ; stream.queue(op + json)}
    else stream.queue(sep + json)
  },
  function (data) {
    if(!anyData) stream.queue(op)
    stream.queue(cl)

    stream.queue(null)
  })

  return stream
}

if(!module.parent && process.title !== 'browser') {
  process.stdin
    .pipe(exports.parse(process.argv[2]))
    .pipe(exports.stringify())
    .pipe(process.stdout)
}
<|endoftext|>


<commit_before>module.exports = function () {

/*
* Format of a permission {
* role: 'basic-user' || {'basic-user':{match: true}}
* customValidator: functionName
* }
*/

//  TODO:50 ensure is_own_dojo for dojo-admin && belongs_to for champion

  return {
    'cd-dojos':{
      'get_dojo_config': [{
        role: 'none'
      }],
      'search_bounding_box': [{
        role: 'none'
      }],
      //Used by front-e resolver, must restrict fields
      'find': [{
        role: 'none'
      }],
      'search': [{
        role: 'cdf-admin'
      }],
      'create': [{
        role: 'basic-user',
        userType: 'parent-guardian'
      },
      { role: 'basic-user',
        userType: 'champion'
      },
      { role: 'basic-user',
        userType: 'mentor'
      }],
      'update': [{
        role: 'basic-user',
        customValidator: [{
            role: 'cd-dojos',
            cmd: 'have_permissions',
            perm: 'dojo-admin'
        }]
      }],
      'update_image': [{
        role: 'basic-user',
        customValidator: [{
            role: 'cd-dojos',
            cmd: 'have_permissions',
            perm: 'dojo-admin'
        }]
      }],
      'delete': [{
        role: 'cdf-admin',
      }],
      'dojos_by_country': [{
        role: 'none'
      }],
      'list': [{
        role: 'none',
      }],
      'my_dojos': [{
        role: 'basic-user'
      }],
      'load': [{
        role: 'none'
      }],
      'bulk_update': [{
        role: 'cdf-admin'
      }],
      'bulk_delete': [{
        role: 'cdf-admin'
      }],
      'uncompleted_dojos': [{
        role: 'basic-user',
        userType: 'champion',
        extendedUserTypes: true
      }],

      'get_stats': [{
        role: 'cdf-admin'
      }],

      //  We can't enforce to be a champion, elsewhat no user appart from champion can start a dojo
      //  NOTE : No need for a check if the user is the one who started this lead if the args extend user
      'save_dojo_lead': [{
        role: 'basic-user',
        // userType: 'champion',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'is_own_lead'
        }]
      }],
      'update_dojo_lead': [{
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'is_own_lead'
        }]
      }],

      'load_user_dojo_lead': [{
        role: 'basic-user'
      }],
      'load_dojo_lead': [{
        role: 'basic-user',
        userType: 'champion',
        extendedUserTypes: true,
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'own_dojo'
        }]
      }, {
        role: 'cdf-admin'
      }],
      //  TODO:140 strengthen ?
      'search_dojo_leads': [{
        role: 'basic-user'
      }],

      'load_setup_dojo_steps': [{
        role: 'basic-user'
      }],

      //  TODO:120 split as "belongs_to_dojo"
      'load_usersdojos': [{
        role: 'basic-user'
      }],

      'load_dojo_users': [{
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }],

      'dojos_for_user': [{
        role: 'basic-user'
      }],

      //  TODO:130 split join from manage userdojos
      'save_usersdojos': [{
        role: 'basic-user'
      }],
      'remove_usersdojos': [ {
        role: 'basic-user',
        customValidator:[{
          role: 'cd-users',
          cmd: 'is_self'
        }]
      } ,{
        role: 'basic-user',
        customValidator:[{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }
    ],
      'export_dojo_users': [{
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }],
      'generate_user_invite_token': [{
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }],
      'accept_user_invite': [{
        role: 'basic-user'
      }],
      'request_user_invite': [{
        role: 'basic-user'
      }],
      'accept_user_request': [{
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }],

      'update_founder': [{
        role: 'basic-user',
        userType: 'champion',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'is_founder'
        }]
      }],

      'notify_all_members': [
      {
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }],

      //  It returns an static object, don't be afraid
      'get_user_permissions': [{
        role: 'none',
      }],
      'get_user_types': [{
        role: 'none'
      }],

      'search_nearest_dojos': [{
        role: 'none'
      }],

      'list_countries': [{
        role: 'none'
      }],
      'list_places': [{
        role: 'none'
      }],
      //  Not even used
      'countries_lat_long': [{
        role: 'none'
      }],
      'continent_codes': [{
        role: 'none'
      }],
      'poll_count': [{
        role: 'none'
      }],
      // It's by design, but we know it's insecure as it could allow to vote as as another dojo
      'save_poll_result': [{
        role: 'none'
      }],
      'get_poll_setup': [{
        role: 'none'
      }],
      'get-poll-results': [{
        role: 'none'
      }],
      'send_test_email_poll': [{
       role: 'cdf-admin'
      }],
      'start_poll': [{
       role: 'cdf-admin'
     }],
     'queue_email_poll': [{
      role: 'cdf-admin'
     }]
    }
  };
};
<commit_msg>Fix for accepting mentor/champion join requests<commit_after>module.exports = function () {

/*
* Format of a permission {
* role: 'basic-user' || {'basic-user':{match: true}}
* customValidator: functionName
* }
*/

//  TODO:50 ensure is_own_dojo for dojo-admin && belongs_to for champion

  return {
    'cd-dojos':{
      'get_dojo_config': [{
        role: 'none'
      }],
      'search_bounding_box': [{
        role: 'none'
      }],
      //Used by front-e resolver, must restrict fields
      'find': [{
        role: 'none'
      }],
      'search': [{
        role: 'cdf-admin'
      }],
      'create': [{
        role: 'basic-user',
        userType: 'parent-guardian'
      },
      { role: 'basic-user',
        userType: 'champion'
      },
      { role: 'basic-user',
        userType: 'mentor'
      }],
      'update': [{
        role: 'basic-user',
        customValidator: [{
            role: 'cd-dojos',
            cmd: 'have_permissions',
            perm: 'dojo-admin'
        }]
      }],
      'update_image': [{
        role: 'basic-user',
        customValidator: [{
            role: 'cd-dojos',
            cmd: 'have_permissions',
            perm: 'dojo-admin'
        }]
      }],
      'delete': [{
        role: 'cdf-admin',
      }],
      'dojos_by_country': [{
        role: 'none'
      }],
      'list': [{
        role: 'none',
      }],
      'my_dojos': [{
        role: 'basic-user'
      }],
      'load': [{
        role: 'none'
      }],
      'bulk_update': [{
        role: 'cdf-admin'
      }],
      'bulk_delete': [{
        role: 'cdf-admin'
      }],
      'uncompleted_dojos': [{
        role: 'basic-user',
        userType: 'champion',
        extendedUserTypes: true
      }],

      'get_stats': [{
        role: 'cdf-admin'
      }],

      //  We can't enforce to be a champion, elsewhat no user appart from champion can start a dojo
      //  NOTE : No need for a check if the user is the one who started this lead if the args extend user
      'save_dojo_lead': [{
        role: 'basic-user',
        // userType: 'champion',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'is_own_lead'
        }]
      }],
      'update_dojo_lead': [{
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'is_own_lead'
        }]
      }],

      'load_user_dojo_lead': [{
        role: 'basic-user'
      }],
      'load_dojo_lead': [{
        role: 'basic-user',
        userType: 'champion',
        extendedUserTypes: true,
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'own_dojo'
        }]
      }, {
        role: 'cdf-admin'
      }],
      //  TODO:140 strengthen ?
      'search_dojo_leads': [{
        role: 'basic-user'
      }],

      'load_setup_dojo_steps': [{
        role: 'basic-user'
      }],

      //  TODO:120 split as "belongs_to_dojo"
      'load_usersdojos': [{
        role: 'basic-user'
      }],

      'load_dojo_users': [{
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }],

      'dojos_for_user': [{
        role: 'basic-user'
      }],

      //  TODO:130 split join from manage userdojos
      'save_usersdojos': [{
        role: 'basic-user'
      }],
      'remove_usersdojos': [ {
        role: 'basic-user',
        customValidator:[{
          role: 'cd-users',
          cmd: 'is_self'
        }]
      } ,{
        role: 'basic-user',
        customValidator:[{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }
    ],
      'export_dojo_users': [{
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }],
      'generate_user_invite_token': [{
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }],
      'accept_user_invite': [{
        role: 'basic-user'
      }],
      'request_user_invite': [{
        role: 'basic-user'
      }],
      'accept_user_request': [{
        // No validator here as check is very custom, and is done already in the actual command code.
        role: 'basic-user'
      }],

      'update_founder': [{
        role: 'basic-user',
        userType: 'champion',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'is_founder'
        }]
      }],

      'notify_all_members': [
      {
        role: 'basic-user',
        customValidator: [{
          role: 'cd-dojos',
          cmd: 'have_permissions',
          perm: 'dojo-admin'
        }]
      }],

      //  It returns an static object, don't be afraid
      'get_user_permissions': [{
        role: 'none',
      }],
      'get_user_types': [{
        role: 'none'
      }],

      'search_nearest_dojos': [{
        role: 'none'
      }],

      'list_countries': [{
        role: 'none'
      }],
      'list_places': [{
        role: 'none'
      }],
      //  Not even used
      'countries_lat_long': [{
        role: 'none'
      }],
      'continent_codes': [{
        role: 'none'
      }],
      'poll_count': [{
        role: 'none'
      }],
      // It's by design, but we know it's insecure as it could allow to vote as as another dojo
      'save_poll_result': [{
        role: 'none'
      }],
      'get_poll_setup': [{
        role: 'none'
      }],
      'get-poll-results': [{
        role: 'none'
      }],
      'send_test_email_poll': [{
       role: 'cdf-admin'
      }],
      'start_poll': [{
       role: 'cdf-admin'
     }],
     'queue_email_poll': [{
      role: 'cdf-admin'
     }]
    }
  };
};
<|endoftext|>


<commit_before>(function(window) {

  var hasVibration = 'vibrate' in navigator;
  var container = document.getElementById('demoPayment');
  var successMsg = document.getElementById('msg-success');

  function showError() {
    container.classList.add('shake');

    if (hasVibration) {
      navigator.vibrate(200);
    }

    setTimeout(function() {
      container.classList.remove('shake');
    }, 200);
  }

  document.getElementById('df-email').addEventListener('invalid', showError);
  document.getElementById('df-amount').addEventListener('invalid', showError);

  document.getElementById('d-form').addEventListener('submit', function(eve) {
    eve.preventDefault();
    this.setAttribute('hidden', 'hidden');
    successMsg.removeAttribute('hidden');
  });

}(this));<commit_msg>Update index.js file.<commit_after>(function(window) {

  var hasVibration = 'vibrate' in navigator;
  var container = document.getElementById('demoPayment');
  var successMsg = document.getElementById('msg-success');
  var email = document.getElementById('df-email');
  var amount = document.getElementById('df-amount');
  var form = document.getElementById('d-form');

  function showError() {
    container.classList.add('shake');

    if (hasVibration) {
      navigator.vibrate(200);
    }

    setTimeout(function() {
      container.classList.remove('shake');
    }, 200);
  }

  email.addEventListener('invalid', showError);
  amount.addEventListener('invalid', showError);

  form.addEventListener('submit', function(eve) {
    eve.preventDefault();
    this.setAttribute('hidden', 'hidden');
    successMsg.removeAttribute('hidden');
  });

}(this));<|endoftext|>


<commit_before>describe('Gremlin', function () {

    it('the namespace should exist', function () {
        expect(Gremlin).to.be.an('object');
        expect(G).to.be.an('object');
        expect(G).to.equal(Gremlin);
    });

    it('should expose the main gremlin.js API', function () {
        //expect(G).to.have.property('add', 'debug','define','Gizmo','Helper','on','registerExtension','ON_ELEMENT_FOUND','ON_DEFINITION_PENDING','ON_GREMLIN_LOADED');
        expect(G).to.have.property('add')
        expect(G.add).to.be.a('function');

        expect(G).to.have.property('debug');
        expect(G.debug).to.be.a(util.Debug);

        expect(G).to.have.property('define');
        expect(G.define).to.be.a('function');

        expect(G).to.have.property('Gizmo');
        expect(G.Gizmo).to.equal(gremlinDefinitions.Gizmo);

        expect(G).to.have.property('Helper')
        expect(G.Helper).to.equal(util.Helper);

        expect(G).to.have.property('on');
        expect(G.on).to.be.a('function');

        expect(G).to.have.property('registerExtension');
        expect(G.registerExtension).to.be.a('function')

        expect(G).to.have.property('ON_ELEMENT_FOUND');
        expect(G.ON_ELEMENT_FOUND).to.be.a('string');

        expect(G).to.have.property('ON_DEFINITION_PENDING');
        expect(G.ON_DEFINITION_PENDING).to.be.a('string');

        expect(G).to.have.property('ON_GREMLIN_LOADED');
        expect(G.ON_GREMLIN_LOADED).to.be.a('string');
    });

    it('can add new gremlin classes', function () {

        expect(function () {
            G.add(AddTest)
        }).to.throwError(Error);

        expect(function () {
            G.add('AddTest')
        }).to.throwError(Error);

        var TestGremlin = G.add('AddTest', AddTest);
        expect(TestGremlin).to.equal(AddTest);

        expect(function () {
            G.add('AddTest', AddTest);
        }).to.throwError(Error);

        expect(gremlinDefinitions.Pool.getInstance().get('AddTest')).to.be(AddTest);

    });

    it('can define new gremlin classes', function () {
        expect(function () {
            G.define('DefineTest');
        }).to.throwError(Error);

        expect(function () {
            G.define(function () {
            });
        }).to.throwError(Error);

        expect(function () {
            G.define('DefineTest', function () {
            }, 'foo', 'foo');
        }).to.throwError(Error);

        expect(function () {
            G.define('DefineTest', function () {
            }, function () {
            });
        }).to.throwError(Error);

        var TestGremlin = G.define('DefineTest', function () {
        }, {
            foo: 'bar'
        }, {
            FOO: "BAR"
        });

        expect(TestGremlin).to.have.property('FOO');
        expect(TestGremlin.FOO).to.equal('BAR');

        expect(TestGremlin.prototype).to.have.property('foo');
        expect(TestGremlin.prototype.foo).to.equal('bar');

    });

    it('instantiates new gremlins', function (done) {
        var el = document.createElement('div'),
            elCoffee = document.createElement('div');
        el.setAttribute('data-gremlin', 'CreateTest');
        elCoffee.setAttribute('data-gremlin', 'CreateTestCoffee');

        document.body.appendChild(el);
        document.body.appendChild(elCoffee);

        var TestGremlin = G.define('CreateTest', function () {
            try {
                expect(this.el).to.equal(el);
                expect(this.klass).to.equal(TestGremlin);
                expect(this.id).to.be.a('number');
                expect(this.data).to.be.an('object');
                //done();
            } catch (e) {
                done(e);
            }
        });

        var CreateTestGremlin = G.add('CreateTestCoffee', CreateTest);

        window.setTimeout(function () {
            try {
                var g = elCoffee.__gremlin;
                expect(elCoffee.className).to.equal('gremlin-ready');
                expect(g.el).to.equal(elCoffee);
                expect(g.klass).to.equal(CreateTestGremlin);
                expect(g.id).to.be.a('number');
                expect(g.data).to.be.an('object');
                done();
            } catch (e) {
                done(e);
            }
        }, 600)
    });

    it('handles data attributes correctly', function (done) {
        var el = document.createElement('div'),
            complex = {
                foo: 'bar',
                deep: {
                    foo: 'bar'
                }
            };
        el.setAttribute('data-gremlin', 'DataTest');
        el.setAttribute('data-string', 'foo');
        el.setAttribute('data-number', "42");
        el.setAttribute('data-yes', 'true');
        el.setAttribute('data-no', 'false');
        el.setAttribute('data-object', JSON.stringify(complex));
        el.setAttribute('data-with-long-name', 'foo');

        document.body.appendChild(el);
        var TestGremlin = G.define('DataTest', function () {
            try {
                expect(this.data).to.have.property('string')
                expect(this.data.string).to.be('foo');

                expect(this.data).to.have.property('number');
                expect(this.data.number).to.be(42);

                expect(this.data).to.have.property('yes');
                expect(this.data.yes).to.be.ok();

                expect(this.data).to.have.property('no');
                expect(this.data.no).not.to.be.ok();

                expect(this.data).to.have.property('object');
                expect(this.data.object).to.eql(complex);

                expect(this.data).to.have.property('withLongName');
                expect(this.data.withLongName).to.be('foo');

                done();
            } catch (e) {
                done(e);
            }
        });
    });

    it('puts unavailble gremlins into a queue', function (done) {
        var el = document.createElement('div');
        el.setAttribute('data-gremlin', 'PendingTest');
        document.body.appendChild(el);

        window.setTimeout(function () {
            try {
                expect(el.className).to.equal('gremlin-loading gremlin-definition-pending');
                done();
            } catch (e) {
                done(e);
            }
        }, 600)

    });

    it('highlights gremlins without a name', function (done) {
        var el = document.createElement('div');
        el.setAttribute('data-gremlin', '');
        document.body.appendChild(el);

        window.setTimeout(function () {
            try {
                expect(el.className).to.equal('gremlin-error');
                done();
            } catch (e) {
                done(e);
            }
        }, 600)

    });

    it('lazy loads gremlin elements', function (done) {
        var el = document.createElement('div');
        el.setAttribute('data-gremlin', 'LazyTest');
        el.setAttribute('data-gremlin-lazy', 'true');
        el.style.marginTop = "3000px";
        document.body.appendChild(el);

        G.define('LazyTest', function () {
            try {
                expect(this.el).to.equal(el);
                done();
                el.parentNode.removeChild(el);
                window.scrollTo(0, 0);
            } catch (e) {
                done(e);
            }
        });
        window.setTimeout(function () {
            try {
                expect(el.className).to.equal('gremlin-loading');
                window.scrollTo(0, document.body.scrollHeight);
            } catch (e) {
                done(e);
            }
        }, 600);

    });

    it('dispatches event when gremlin element was found', function (done) {
        var el = document.createElement('div'),
            onFound = function (foundEl) {
                try {
                    expect(foundEl).to.equal(el);
                    done();
                } catch (e) {
                    done(e);
                }

                G.off(G.ON_ELEMENT_FOUND, onFound);
                el.parentNode.removeChild(el);
            };
        el.setAttribute('data-gremlin', 'EventOnFoundTest');

        G.on(G.ON_ELEMENT_FOUND, onFound);
        document.body.appendChild(el);
    });

    it('dispatches event when gremlin definition is pending', function (done) {
        var el = document.createElement('div'),
            onPending = function (foundEl) {
                try {
                    expect(foundEl).to.equal(el);
                    done();
                } catch (e) {
                    done(e);
                }

                G.off(G.ON_DEFINITION_PENDING, onPending);
                el.parentNode.removeChild(el);
            };
        el.setAttribute('data-gremlin', 'EventOnPendingTest');

        G.on(G.ON_DEFINITION_PENDING, onPending);
        document.body.appendChild(el);
    });

    it('dispatches event when gremlin instance was created', function (done) {
        var el = document.createElement('div'),
            onCreated = function (foundEl) {
                try {
                    expect(foundEl).to.equal(el);
                    done();
                } catch (e) {
                    done(e);
                }

                G.off(G.ON_GREMLIN_LOADED, onCreated);
                el.parentNode.removeChild(el);
            };
        el.setAttribute('data-gremlin', 'EventOnLoadedTest');
        G.on(G.ON_GREMLIN_LOADED, onCreated);
        document.body.appendChild(el);

        G.define('EventOnLoadedTest', function () {

        });
    });
});<commit_msg>new test cae<commit_after>describe('Gremlin', function () {

    it('the namespace should exist', function () {
        expect(Gremlin).to.be.an('object');
        expect(G).to.be.an('object');
        expect(G).to.equal(Gremlin);
    });

    it('should expose the main gremlin.js API', function () {
        //expect(G).to.have.property('add', 'debug','define','Gizmo','Helper','on','registerExtension','ON_ELEMENT_FOUND','ON_DEFINITION_PENDING','ON_GREMLIN_LOADED');
        expect(G).to.have.property('add')
        expect(G.add).to.be.a('function');

        expect(G).to.have.property('debug');
        expect(G.debug).to.be.a(util.Debug);

        expect(G).to.have.property('define');
        expect(G.define).to.be.a('function');

        expect(G).to.have.property('Gizmo');
        expect(G.Gizmo).to.equal(gremlinDefinitions.Gizmo);

        expect(G).to.have.property('Helper')
        expect(G.Helper).to.equal(util.Helper);

        expect(G).to.have.property('on');
        expect(G.on).to.be.a('function');

        expect(G).to.have.property('registerExtension');
        expect(G.registerExtension).to.be.a('function')

        expect(G).to.have.property('ON_ELEMENT_FOUND');
        expect(G.ON_ELEMENT_FOUND).to.be.a('string');

        expect(G).to.have.property('ON_DEFINITION_PENDING');
        expect(G.ON_DEFINITION_PENDING).to.be.a('string');

        expect(G).to.have.property('ON_GREMLIN_LOADED');
        expect(G.ON_GREMLIN_LOADED).to.be.a('string');
    });

    it('can add new gremlin classes', function () {

        expect(function () {
            G.add(AddTest)
        }).to.throwError(Error);

        expect(function () {
            G.add('AddTest')
        }).to.throwError(Error);

        var TestGremlin = G.add('AddTest', AddTest);
        expect(TestGremlin).to.equal(AddTest);

        expect(function () {
            G.add('AddTest', AddTest);
        }).to.throwError(Error);

        expect(gremlinDefinitions.Pool.getInstance().get('AddTest')).to.be(AddTest);

    });

    it('can define new gremlin classes', function () {
        expect(function () {
            G.define('DefineTest');
        }).to.throwError(Error);

        expect(function () {
            G.define(function () {
            });
        }).to.throwError(Error);

        expect(function () {
            G.define('DefineTest', function () {
            }, 'foo', 'foo');
        }).to.throwError(Error);

        expect(function () {
            G.define('DefineTest', function () {
            }, function () {
            });
        }).to.throwError(Error);

        var TestGremlin = G.define('DefineTest', function () {
        }, {
            foo: 'bar'
        }, {
            FOO: "BAR"
        });

        expect(TestGremlin).to.have.property('FOO');
        expect(TestGremlin.FOO).to.equal('BAR');

        expect(TestGremlin.prototype).to.have.property('foo');
        expect(TestGremlin.prototype.foo).to.equal('bar');

    });

    it('instantiates new gremlins', function (done) {
        var el = document.createElement('div'),
            elCoffee = document.createElement('div');
        el.setAttribute('data-gremlin', 'CreateTest');
        elCoffee.setAttribute('data-gremlin', 'CreateTestCoffee');

        document.body.appendChild(el);
        document.body.appendChild(elCoffee);

        var TestGremlin = G.define('CreateTest', function () {
            try {
                expect(this.el).to.equal(el);
                expect(this.klass).to.equal(TestGremlin);
                expect(this.id).to.be.a('number');
                expect(this.data).to.be.an('object');
                //done();
            } catch (e) {
                done(e);
            }
        });

        var CreateTestGremlin = G.add('CreateTestCoffee', CreateTest);

        window.setTimeout(function () {
            try {
                var g = elCoffee.__gremlin;
                expect(elCoffee.className).to.equal('gremlin-ready');
                expect(g.el).to.equal(elCoffee);
                expect(g.klass).to.equal(CreateTestGremlin);
                expect(g.id).to.be.a('number');
                expect(g.data).to.be.an('object');
                done();
            } catch (e) {
                done(e);
            }
        }, 600)
    });

    it('instantiates multiple gremlins on a singe element');

    it('handles data attributes correctly', function (done) {
        var el = document.createElement('div'),
            complex = {
                foo: 'bar',
                deep: {
                    foo: 'bar'
                }
            };
        el.setAttribute('data-gremlin', 'DataTest');
        el.setAttribute('data-string', 'foo');
        el.setAttribute('data-number', "42");
        el.setAttribute('data-yes', 'true');
        el.setAttribute('data-no', 'false');
        el.setAttribute('data-object', JSON.stringify(complex));
        el.setAttribute('data-with-long-name', 'foo');

        document.body.appendChild(el);
        var TestGremlin = G.define('DataTest', function () {
            try {
                expect(this.data).to.have.property('string')
                expect(this.data.string).to.be('foo');

                expect(this.data).to.have.property('number');
                expect(this.data.number).to.be(42);

                expect(this.data).to.have.property('yes');
                expect(this.data.yes).to.be.ok();

                expect(this.data).to.have.property('no');
                expect(this.data.no).not.to.be.ok();

                expect(this.data).to.have.property('object');
                expect(this.data.object).to.eql(complex);

                expect(this.data).to.have.property('withLongName');
                expect(this.data.withLongName).to.be('foo');

                done();
            } catch (e) {
                done(e);
            }
        });
    });

    it('puts unavailble gremlins into a queue', function (done) {
        var el = document.createElement('div');
        el.setAttribute('data-gremlin', 'PendingTest');
        document.body.appendChild(el);

        window.setTimeout(function () {
            try {
                expect(el.className).to.equal('gremlin-loading gremlin-definition-pending');
                done();
            } catch (e) {
                done(e);
            }
        }, 600)

    });

    it('highlights gremlins without a name', function (done) {
        var el = document.createElement('div');
        el.setAttribute('data-gremlin', '');
        document.body.appendChild(el);

        window.setTimeout(function () {
            try {
                expect(el.className).to.equal('gremlin-error');
                done();
            } catch (e) {
                done(e);
            }
        }, 600)

    });

    it('lazy loads gremlin elements', function (done) {
        var el = document.createElement('div');
        el.setAttribute('data-gremlin', 'LazyTest');
        el.setAttribute('data-gremlin-lazy', 'true');
        el.style.marginTop = "3000px";
        document.body.appendChild(el);

        G.define('LazyTest', function () {
            try {
                expect(this.el).to.equal(el);
                done();
                el.parentNode.removeChild(el);
                window.scrollTo(0, 0);
            } catch (e) {
                done(e);
            }
        });
        window.setTimeout(function () {
            try {
                expect(el.className).to.equal('gremlin-loading');
                window.scrollTo(0, document.body.scrollHeight);
            } catch (e) {
                done(e);
            }
        }, 600);

    });

    it('dispatches event when gremlin element was found', function (done) {
        var el = document.createElement('div'),
            onFound = function (foundEl) {
                try {
                    expect(foundEl).to.equal(el);
                    done();
                } catch (e) {
                    done(e);
                }

                G.off(G.ON_ELEMENT_FOUND, onFound);
                el.parentNode.removeChild(el);
            };
        el.setAttribute('data-gremlin', 'EventOnFoundTest');

        G.on(G.ON_ELEMENT_FOUND, onFound);
        document.body.appendChild(el);
    });

    it('dispatches event when gremlin definition is pending', function (done) {
        var el = document.createElement('div'),
            onPending = function (foundEl) {
                try {
                    expect(foundEl).to.equal(el);
                    done();
                } catch (e) {
                    done(e);
                }

                G.off(G.ON_DEFINITION_PENDING, onPending);
                el.parentNode.removeChild(el);
            };
        el.setAttribute('data-gremlin', 'EventOnPendingTest');

        G.on(G.ON_DEFINITION_PENDING, onPending);
        document.body.appendChild(el);
    });

    it('dispatches event when gremlin instance was created', function (done) {
        var el = document.createElement('div'),
            onCreated = function (foundEl) {
                try {
                    expect(foundEl).to.equal(el);
                    done();
                } catch (e) {
                    done(e);
                }

                G.off(G.ON_GREMLIN_LOADED, onCreated);
                el.parentNode.removeChild(el);
            };
        el.setAttribute('data-gremlin', 'EventOnLoadedTest');
        G.on(G.ON_GREMLIN_LOADED, onCreated);
        document.body.appendChild(el);

        G.define('EventOnLoadedTest', function () {

        });
    });
});<|endoftext|>